Bash 检查 $var 是否在数字范围内
Bash check if $var is in number range
我做了一个 bash 函数,它有两个参数。
= start time
= end time
两个值都以小时格式表示,因此它们可以从 00
到 23
。
想法是函数采用开始和结束时间参数,并在此时间范围内播放一些视频片段。
我第一次想到这个:
TIME=$(date +%H)
# # #
#
# Check if its time to play files
# = begin hour, = End hour, = folder with video files
#
# # #
check_if_time_to_play(){
# If current TIME is between begin and end time
if [ $TIME -ge "" ] && [ $TIME -lt "" ]; then
# Make sure the folder is not empty
if find "" -mindepth 1 -print -quit | grep -q .; then
# It's not emty, play the clips
play_files ""
else
continue # It's empty! dont play the non-existing clips
fi
else
continue # TIME is not in range, dont play the clips
fi
}
但我很快意识到这不是最新的。
如果我提交,说 =22
、=05
和 $TIME=23
剪辑将不会播放。
所以我在考虑在最后一个 else
语句中添加一个额外的 if
。
像这样:
# check for times where start is bigger than end (ie. 22-05)
if [ "" -le "" ]; then
#and in here do some range check
fi
所以在这个 if
里面,我正在考虑做一些范围检查,但我不确定该怎么做。
我在想:
if [[ $TIME -eq {..24} ] ]&& [ $TIME -eq {00..} ]; then
play_files ""
fi
所以这个 offcause 不起作用 - 所以我的问题是:
有没有一种方法可以根据一系列数字检查 00
到 23
?
或者如果你明白我在做什么,有没有更好的方法?
如果你不明白,请告诉我 - 我会尽力解释更多。
提前致谢!
为什么不使用完整日期? GNU date
(在 Linux 上可用)有一个漂亮的 -d
开关,可以让您打印任意次数。如果你给它一个小时,它会打印那个小时的完整日期今天:
$ date -d 23:00
Tue Mar 24 23:00:00 EET 2015
您可以告诉它以秒为单位打印自纪元以来的时间,以便于比较:
$ date -d 23:00 +%s
1427230800
最后,您可以假设如果结束日期小于开始日期,那么结束日期指的是明天。考虑到这一点,您的脚本的工作版本可能是:
#!/usr/bin/env bash
TIME=$(date +%s)
check_if_time_to_play(){
# If current TIME is between begin and end time
if [ $TIME -ge "" ] && [ $TIME -lt "" ]; then
# Make sure the folder is not empty
if find "" -mindepth 1 -print -quit | grep -q .; then
# It's not emty, play the clips
#play_files ""
echo playing
fi
else
echo "Out of range: $TIME : : "
fi
}
## Get the start and end times
start="$(date -d "" +%s)"
end="$(date -d "" +%s)"
## Deal with end times that are smaller than start times.
## We will assume that they refer to tomorrow's date.
[ "$start" -gt "$end" ] && end="$(date -d " + 1 day" +%s)"
check_if_time_to_play "$start" "$end" ""
请注意,我删除了您的 else continue
块,因为它们在 if
语句中没有意义。
尝试以下方法,它使用 bash 的 shell arithmetic,它提供 使用熟悉的 C 风格语法的算术计算 在几种情况下:
- 作为测试或计算,没有输出,形式为
((...))
或let ...
- 作为计算,输出结果(算术展开),形式为
$((...))
- 使用 整数变量声明 和 时 用
declare -i
或 local -i
声明
- 在 bash 需要数字的其他上下文中,例如 array subscripts 或 substring indices.
# # #
#
# Check if its time to play files
# = hour now, = begin hour, = End hour, = folder with video files
#
# # #
check_if_time_to_play() {
# Make sure the arguments are interpreted as *decimal* integers
# by evaluating them in an arithmetic context (-i) with prefix '10#',
# indicating number base 10.
# (A leading '0' would cause intepretation as *octal*.)
local -i hourNow=10# startHour=10# endHour=10# play
local dir=
# Make sure the folder is not empty.
if ! find "$dir" -mindepth 1 -print -quit | grep -q .; then
return # It's empty! Don't play the non-existing clips.
fi
# Determine if current hour is between begin and end time.
play=0
if (( startHour < endHour )); then
if (( hourNow >= startHour && hourNow < endHour )); then
play=1
fi
else # startHour > endHour: overnight hours
if (( hourNow >= startHour || hourNow < endHour )); then
play=1
fi
fi
if (( play )); then
# Play the clips
play_files "$dir"
else
: # Current hour is not in range, don't play the clips.
fi
}
示例调用:
check_if_time_to_play $(date +%H) 22 05 .
# Hard-coded, to test logic
check_if_time_to_play 23 22 05 .
check_if_time_to_play 11 10 18 .
- 请注意,我已将当前时间作为第一个参数。 (此外,最好避免使用全大写的 shell 变量名称,例如
TIME
以避免与环境或特殊 shell 变量发生冲突。
$((...))
输出计算结果,而((...))
将结果解释为测试。
- 开始时间 > 结束时间(隔夜)时间范围的情况在单独的
if
分支中处理,其中当前时间必须 或者 晚于开始时间 或 早于(第二天早上)结束时间。
我做了一个 bash 函数,它有两个参数。
= start time
= end time
两个值都以小时格式表示,因此它们可以从 00
到 23
。
想法是函数采用开始和结束时间参数,并在此时间范围内播放一些视频片段。
我第一次想到这个:
TIME=$(date +%H)
# # #
#
# Check if its time to play files
# = begin hour, = End hour, = folder with video files
#
# # #
check_if_time_to_play(){
# If current TIME is between begin and end time
if [ $TIME -ge "" ] && [ $TIME -lt "" ]; then
# Make sure the folder is not empty
if find "" -mindepth 1 -print -quit | grep -q .; then
# It's not emty, play the clips
play_files ""
else
continue # It's empty! dont play the non-existing clips
fi
else
continue # TIME is not in range, dont play the clips
fi
}
但我很快意识到这不是最新的。
如果我提交,说 =22
、=05
和 $TIME=23
剪辑将不会播放。
所以我在考虑在最后一个 else
语句中添加一个额外的 if
。
像这样:
# check for times where start is bigger than end (ie. 22-05)
if [ "" -le "" ]; then
#and in here do some range check
fi
所以在这个 if
里面,我正在考虑做一些范围检查,但我不确定该怎么做。
我在想:
if [[ $TIME -eq {..24} ] ]&& [ $TIME -eq {00..} ]; then
play_files ""
fi
所以这个 offcause 不起作用 - 所以我的问题是:
有没有一种方法可以根据一系列数字检查 00
到 23
?
或者如果你明白我在做什么,有没有更好的方法?
如果你不明白,请告诉我 - 我会尽力解释更多。
提前致谢!
为什么不使用完整日期? GNU date
(在 Linux 上可用)有一个漂亮的 -d
开关,可以让您打印任意次数。如果你给它一个小时,它会打印那个小时的完整日期今天:
$ date -d 23:00
Tue Mar 24 23:00:00 EET 2015
您可以告诉它以秒为单位打印自纪元以来的时间,以便于比较:
$ date -d 23:00 +%s
1427230800
最后,您可以假设如果结束日期小于开始日期,那么结束日期指的是明天。考虑到这一点,您的脚本的工作版本可能是:
#!/usr/bin/env bash
TIME=$(date +%s)
check_if_time_to_play(){
# If current TIME is between begin and end time
if [ $TIME -ge "" ] && [ $TIME -lt "" ]; then
# Make sure the folder is not empty
if find "" -mindepth 1 -print -quit | grep -q .; then
# It's not emty, play the clips
#play_files ""
echo playing
fi
else
echo "Out of range: $TIME : : "
fi
}
## Get the start and end times
start="$(date -d "" +%s)"
end="$(date -d "" +%s)"
## Deal with end times that are smaller than start times.
## We will assume that they refer to tomorrow's date.
[ "$start" -gt "$end" ] && end="$(date -d " + 1 day" +%s)"
check_if_time_to_play "$start" "$end" ""
请注意,我删除了您的 else continue
块,因为它们在 if
语句中没有意义。
尝试以下方法,它使用 bash 的 shell arithmetic,它提供 使用熟悉的 C 风格语法的算术计算 在几种情况下:
- 作为测试或计算,没有输出,形式为
((...))
或let ...
- 作为计算,输出结果(算术展开),形式为
$((...))
- 使用 整数变量声明 和 时 用
declare -i
或local -i
声明
- 在 bash 需要数字的其他上下文中,例如 array subscripts 或 substring indices.
# # #
#
# Check if its time to play files
# = hour now, = begin hour, = End hour, = folder with video files
#
# # #
check_if_time_to_play() {
# Make sure the arguments are interpreted as *decimal* integers
# by evaluating them in an arithmetic context (-i) with prefix '10#',
# indicating number base 10.
# (A leading '0' would cause intepretation as *octal*.)
local -i hourNow=10# startHour=10# endHour=10# play
local dir=
# Make sure the folder is not empty.
if ! find "$dir" -mindepth 1 -print -quit | grep -q .; then
return # It's empty! Don't play the non-existing clips.
fi
# Determine if current hour is between begin and end time.
play=0
if (( startHour < endHour )); then
if (( hourNow >= startHour && hourNow < endHour )); then
play=1
fi
else # startHour > endHour: overnight hours
if (( hourNow >= startHour || hourNow < endHour )); then
play=1
fi
fi
if (( play )); then
# Play the clips
play_files "$dir"
else
: # Current hour is not in range, don't play the clips.
fi
}
示例调用:
check_if_time_to_play $(date +%H) 22 05 .
# Hard-coded, to test logic
check_if_time_to_play 23 22 05 .
check_if_time_to_play 11 10 18 .
- 请注意,我已将当前时间作为第一个参数。 (此外,最好避免使用全大写的 shell 变量名称,例如
TIME
以避免与环境或特殊 shell 变量发生冲突。 $((...))
输出计算结果,而((...))
将结果解释为测试。- 开始时间 > 结束时间(隔夜)时间范围的情况在单独的
if
分支中处理,其中当前时间必须 或者 晚于开始时间 或 早于(第二天早上)结束时间。