我正在尝试调整来自“Sams 24小时自学Linux”的bash脚本,这是一个名为rmv的安全删除命令。通过调用rmv -d file1 file2等删除文件。在原始脚本中,最多可以使用变量$ 1 $ 2 $ 3 $ 4删除4个文件。 我想通过使用通配符将其扩展为无限数量的文件。 所以我这样做:
for i in $*
do
mv $i $HOME/.trash
done
文件被删除没问题但是命令rmv -d的选项-d也被视为参数和bash对象,它们无法找到。有更好的方法吗?
谢谢, 彼得
#!/bin/bash
# rmv - a safe delete program
# uses a trash directory under your home directory
mkdir $HOME/.trash 2>/dev/null
# four internal script variables are defined
cmdlnopts=false
delete=false
empty=false
list=false
# uses getopts command to look at command line for any options
while getopts "dehl" cmdlnopts; do
case "$cmdlnopts" in
d ) /bin/echo "deleting: \c" $2 $3 $4 $5 ; delete=true ;;
e ) /bin/echo "emptying the trash..." ; empty=true ;;
h ) /bin/echo "safe file delete v1.0"
/bin/echo "rmv -d[elete] -e[mpty] -h[elp] -l[ist] file1-4" ;;
l ) /bin/echo "your .trash directory contains:" ; list=true ;;
esac
done
if [ $delete = true ]
then
for i in $*
do
mv $i $HOME/.trash
done
/bin/echo "rmv finished."
fi
if [ $empty = true ]
then
/bin/echo "empty the trash? \c"
read answer
case "$answer" in
y) rm -i $HOME/.trash/* ;;
n) /bin/echo "trashcan delete aborted." ;;
esac
fi
if [ $list = true ]
then
ls -l $HOME/.trash
fi
答案 0 :(得分:0)
您可以在此处使用shift。
一旦发现-d
是switch
中的一个选项,您就可以从位置参数中移除-d
。接下来你可以
until [ -z $1 ] ; do
mv $1 $HOME/.trash
shift
done
答案 1 :(得分:0)
getopts
将OPTIND
设置为选项后第一个参数的索引。 (#)
因此,在解析了您可以执行的选项之后:
shift $OPTIND-1
从参数列表中删除选项。
然后使用"$@"
而不是$ *,您可以处理包含空格的文件。
答案 2 :(得分:0)
非常感谢!
我将代码更改为:
#!/bin/bash
# rmv - a safe delete program
# todo: add ability to handle wildcards
# uses a trash directory under your home directory
mkdir $HOME/.trash 2>/dev/null
# four internal script variables are defined
cmdlnopts=false
delete=false
empty=false
list=false
# uses getopts command to look at command line for any options
while getopts "dehl" cmdlnopts; do
case "$cmdlnopts" in
d ) echo -e "deleting: \n" "${@:2}" ; delete=true ;;
e ) echo -e "emptying the trash..." ; empty=true ;;
h ) echo -e "safe file delete v1.0"
echo -e "rmv -d[elete] -e[mpty] -h[elp] -l[ist] file [...]" ;;
l ) echo -e "your .trash directory contains:" ; list=true ;;
esac
done
shift $OPTIND-1
if [ $delete = true ]
then
for i in $@
do
mv $i $HOME/.trash
done
echo "rmv finished."
fi
then
/bin/echo "empty the trash? \c"
read answer
case "$answer" in
y) rm -i $HOME/.trash/* ;;
n) /bin/echo "trashcan delete aborted." ;;
esac
fi
if [ $list = true ]
then
ls -l $HOME/.trash
fi
这会根据需要删除文件但我收到此错误:
/home/peter/rmv: line 21: shift: 2-1: numeric argument required
mv: invalid option -- 'd'
Try `mv --help' for more information.
答案 3 :(得分:0)
您需要使用
shift $(($OPTIND - 1))
去除进程命令行args。试试这个版本:
#!/bin/bash
# rmv - a safe delete program
# uses a trash directory under your home directory
mkdir -p $HOME/.trash
# uses getopts command to look at command line for any options
while getopts "dehl" cmdlnopts; do
case "$cmdlnopts" in
d ) delete=true;;
e ) echo "emptying the trash..." ; empty=true ;;
h ) echo "safe file delete v1.0"
echo "rmv -d[elete] -e[mpty] -h[elp] -l[ist] files" ;;
l ) echo "your .trash directory contains:" ; list=true ;;
esac
done
shift $(($OPTIND - 1))
if [ -n "${delete}" ]; then
echo "deleting: " "${@}"
mv ${@} $HOME/.trash
echo "rmv finished."
fi
if [ -n "${empty}" ]; then
read -p "empty the trash? " answer
case "$answer" in
y) rm -i $HOME/.trash/* ;;
n) echo "trashcan delete aborted." ;;
esac
fi
if [ -n "${list}" ]; then
ls -l $HOME/.trash
fi
答案 4 :(得分:0)
晚会,但对于Google员工,这将产生彼得描述的错误:
shift $OPTIND-1
虽然Jurgen的回复中的语法不会:
shift $(($OPTIND-1))
问题是$ OPTIND-1被解释为一个字符串,而shift不能使用字符串作为参数。 $(())是Bash的arithmetic expansion operator。在其中放入一个字符串,该字符串被计算为算术表达式,并返回该值。