nic*_*ckf 91 validation bash shell
我想出了一个基本的,以帮助自动删除多个文件夹,因为它们变得不必要.
#!/bin/bash
rm -rf ~/myfolder1/$1/anotherfolder
rm -rf ~/myfolder2/$1/yetanotherfolder
rm -rf ~/myfolder3/$1/thisisafolder
Run Code Online (Sandbox Code Playgroud)
这是这样的:
./myscript.sh <{id-number}>
Run Code Online (Sandbox Code Playgroud)
问题是,如果你忘记输入id-number
(就像我之前那样),那么它可能会删除你真正不想删除的很多东西.
有没有办法可以在命令行参数中添加任何形式的验证?在我的情况下,最好检查a)是否有一个参数,b)它的数字,以及c)该文件夹是否存在; 在继续脚本之前.
Bri*_*ell 152
#!/bin/sh
die () {
echo >&2 "$@"
exit 1
}
[ "$#" -eq 1 ] || die "1 argument required, $# provided"
echo $1 | grep -E -q '^[0-9]+$' || die "Numeric argument required, $1 provided"
while read dir
do
[ -d "$dir" ] || die "Directory $dir does not exist"
rm -rf "$dir"
done <<EOF
~/myfolder1/$1/anotherfolder
~/myfolder2/$1/yetanotherfolder
~/myfolder3/$1/thisisafolder
EOF
Run Code Online (Sandbox Code Playgroud)
编辑:我错过了关于检查目录是否存在的部分,所以我添加了,完成脚本.此外,还讨论了评论中提出的问题; 修复了正则表达式,切换==
为eq
.
据我所知,这应该是一个便携式,POSIX兼容的脚本; 它不使用任何bashisms,这实际上很重要,因为/bin/sh
在Ubuntu实际上是dash
这些天,而不是bash
.
lhu*_*ath 21
将sh
通过解决方案Brian Campbell
,而高贵和很好的执行,有一些问题,所以我想我会提供我自己的bash
解决方案.
sh
一个问题:
~/foo
不会扩展到heredocs内的homedirectory.无论何时通过read
声明阅读或在rm
声明中引用.这意味着你会得到No such file or directory
错误.grep
和基本操作等是愚蠢的.特别是当你使用蹩脚的外壳来避免重击"沉重"时.echo
.sh
可以应对它们 - 这就是为什么我几乎总是喜欢bash
它,它更具防弹性,并且在使用时更难以利用).虽然,是的,使用/bin/sh
你的hashbang意味着你必须bash
不惜一切代价避免主义,你可以使用bash
你喜欢的所有主义,甚至在Ubunutu或什么时候,当你诚实并放在#!/bin/bash
顶部.
所以,这是一个bash
更小,更清洁,更透明,可能"更快",更具防弹性的解决方案.
[[ -d $1 && $1 != *[^0-9]* ]] || { echo "Invalid input." >&2; exit 1; }
rm -rf ~/foo/"$1"/bar ...
Run Code Online (Sandbox Code Playgroud)
$1
的rm
声明!-d
检查也将失败,如果$1
是空的,所以这两项检查于一体.=~
在bash中使用,则应将正则表达式放在变量中.在任何情况下,像我这样的球体总是更受欢迎,并且支持更多的bash版本.Joh*_*itb 14
我会用bash的[[
:
if [[ ! ("$#" == 1 && $1 =~ ^[0-9]+$ && -d $1) ]]; then
echo 'Please pass a number that corresponds to a directory'
exit 1
fi
Run Code Online (Sandbox Code Playgroud)
我发现这个常见问题是一个很好的信息来源.
Boi*_*ill 12
不像上面的答案一样防弹,但仍然有效:
#!/bin/bash
if [ "$1" = "" ]
then
echo "Usage: $0 <id number to be cleaned up>"
exit
fi
# rm commands go here
Run Code Online (Sandbox Code Playgroud)
shm*_*ael 10
使用set -u
会导致任何未设置的参数引用立即使脚本失败.
http://www.davidpashley.com/articles/writing-robust-shell-scripts.html
And*_*ewD 10
以下是一些对我有用的方法。您可以在全局脚本命名空间中使用它们(如果在全局命名空间中,则无法引用函数内置变量)
又快又脏的一个衬里
: ${1?' You forgot to supply a directory name'}
Run Code Online (Sandbox Code Playgroud)
输出:
./my_script: line 279: 1: You forgot to supply a directory name
Run Code Online (Sandbox Code Playgroud)
Fancier - 提供函数名称和用法
${1? ERROR Function: ${FUNCNAME[0]}() Usage: " ${FUNCNAME[0]} directory_name"}
Run Code Online (Sandbox Code Playgroud)
输出:
./my_script: line 288: 1: ERROR Function: deleteFolders() Usage: deleteFolders directory_name
Run Code Online (Sandbox Code Playgroud)
添加复杂的验证逻辑,而不会使当前的功能变得混乱
在接收参数的函数或脚本中添加以下行。
: ${1?'forgot to supply a directory name'} && validate $1 || die 'Please supply a valid directory'
Run Code Online (Sandbox Code Playgroud)
然后您可以创建一个验证函数来执行类似的操作
validate() {
#validate input and & return 1 if failed, 0 if succeed
if [[ ! -d "$1" ]]; then
return 1
fi
}
Run Code Online (Sandbox Code Playgroud)
以及一个在失败时中止脚本的 die 函数
die() { echo "$*" 1>&2 ; exit 1; }
Run Code Online (Sandbox Code Playgroud)
对于其他参数,只需添加一行,复制格式即可。
: ${1?' You forgot to supply the first argument'}
: ${2?' You forgot to supply the second argument'}
Run Code Online (Sandbox Code Playgroud)
使用'-z'测试空字符串,使用'-d检查目录.
if [[ -z "$@" ]]; then
echo >&2 "You must supply an argument!"
exit 1
elif [[ ! -d "$@" ]]; then
echo >&2 "$@ is not a valid directory!"
exit 1
fi
Run Code Online (Sandbox Code Playgroud)
test(man test
)的手册页提供了可以在bash中用作布尔运算符的所有可用运算符.在脚本(或函数)的开头使用这些标志进行输入验证,就像在任何其他编程语言中一样.例如:
if [ -z $1 ] ; then
echo "First parameter needed!" && exit 1;
fi
if [ -z $2 ] ; then
echo "Second parameter needed!" && exit 2;
fi
Run Code Online (Sandbox Code Playgroud)
您可以通过执行以下操作来紧凑地验证点a和b:
#!/bin/sh
MYVAL=$(echo ${1} | awk '/^[0-9]+$/')
MYVAL=${MYVAL:?"Usage - testparms <number>"}
echo ${MYVAL}
Run Code Online (Sandbox Code Playgroud)
这给了我们...
$ ./testparams.sh
Usage - testparms <number>
$ ./testparams.sh 1234
1234
$ ./testparams.sh abcd
Usage - testparms <number>
Run Code Online (Sandbox Code Playgroud)
该方法在sh中应该可以正常工作。