我正在尝试创建一个小写/大写文件或目录的脚本。
modify [-r] [-l|-u] <dir/file names...>
我目前正在使用 getopts 来检查标志。但是,我无法运行像修改 -rl 那样递归地小写我的目录/文件的命令。
(编辑)代码:
#!/bin/bash
FLAGS=""
if [ $# -eq 0 ]
then
echo -e "No arguments supplied. \nPlease supply an argument.For more information use -h."
else
while getopts "rluh" opt
do
case $opt in
r)
FLAGS+=r
;;
l)
FLAGS+=l
;;
u)
FLAGS+=u
;;
h)
FLAGS+=h
;;
*)
echo "Unrecognized argument. Please enter -h for information"
esac
done
fi
if [[ "$FLAGS" == "l" && "$2" -eq 0 ]]
then
echo "file to modify $2"
elif [[ "$FLAGS" == "h" && "$2" -eq 0 ]]
then
echo "Some info"
fi
exit 0
答案1
如果为每个激活的选项设置单独的标志会更容易,这样您就不需要再解析另一个字符串来检查是否使用了某个选项。
例如:
#!/bin/bash
self=$0
show_help () {
cat <<END_HELP
Usage: $self [-r] [-l|-u] pathname [...]
Options:
info about options here
END_HELP
}
recurse=0 # don't recurse by default
lowercase=1 # lowercase by default
while getopts rluh opt; do
case $opt in
r) recurse=1 ;;
l) lowercase=1 ;;
u) lowercase=0 ;;
h) show_help
exit ;;
*) echo 'Error in parsing options' >&2
exit 1
esac
done
shift "$(( OPTIND - 1 ))"
for pathname do
if [ -d "$pathname" ] && [ "$recurse" -eq 1 ]; then
# recurse here
fi
if [ "$lowercase" -eq 1 ]; then
# turn into lowercase
else
# turn into uppercase
fi
done
请注意,后面的代码shift
只是示例代码。我建议您考虑使用循环来代替find
递归(可能在所有情况下,即使recursion
标志不是放)。
顺便说一句shift
, 删除了所有已解析的选项,"$@"
以便只有路径名操作数保留在位置参数列表中。这就是循环之后迭代的内容。
上面编写的代码使用合理的默认值(这些应该在帮助文本中提及)。这意味着无需任何选项即可运行脚本。作为旁注,运行该工具不任何参数都可能不会导致错误。没有工作要做,所以不应该做任何工作。
答案2
您将标志字母连接到单个字符串,因此使用myscript -l -r
,您会得到FLAGS=lr
,它不等于l
或r
。
您可以使用模式匹配而不是相等测试来处理这个问题:
if [[ $FLAGS = *r* ]]; then
echo "flag -r was given"
或为每个标志添加不同的变量:
r_flag=
l_flag=
while getopts "rluh" opt; do
case $opt in
r) r_flag=1;;
...
if [[ $r_flag ]]; then
echo "flag -r was given"
无论如何,您很可能希望在循环shift $(( OPTIND - 1 ))
之后执行while getopts
,以便从位置参数中删除 , ... 处理的选项,而, ...getopts
中剩下的是选项之后给出的脚本参数。$1
$2
答案3
类似的东西FLAGS+=r
会将 r 附加到 FLAGS 上。对于modify -r -l
FLAGS 因此将是rl
。每个选项应该使用一个变量 ( FLAG_r
)。
仅当脚本"$2" -eq 0
获取两个目录名称(第二个为0
.更好的比较是"$2" = ""
。