validation参数到一个Bash脚本
我想出了一个基本的帮助,以便在不需要的时候自动删除大量文件夹。
#!/bin/bash rm -rf ~/myfolder1/$1/anotherfolder rm -rf ~/myfolder2/$1/yetanotherfolder rm -rf ~/myfolder3/$1/thisisafolder
这是这样引起的:
./myscript.sh <{id-number}>
问题是,如果你忘记inputid-number
(就像我那样) ,那么它可能会删除很多你真的不想删除的东西。
有没有一种方法可以将任何forms的validation添加到命令行参数? 在我的情况下,这将是很好的检查,a)有一个参数,b)它的数字,和c)该文件夹存在; 在继续脚本之前。
#!/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
编辑 :我错过了有关检查目录是否存在的部分,所以我join了,完成脚本。 此外,还处理了评论中提出的问题; 修正了正则expression式,从==
切换到eq
。
据我所知,这应该是一个可移植的,POSIX兼容的脚本; 它不使用任何bashisms,这实际上很重要,因为Ubuntu上的/bin/sh
实际上是dash
,而不是bash
。
Brian Campbell
( Brian Campbell
这个解决scheme虽然高贵而且执行得很好,但有一些问题,所以我想我会提供自己的解决scheme。
问题一:
-
~/foo
中的波浪号不会扩展到heredocs中的homedirectory。 而且当它被read
语句read
或在rm
语句中引用时。 这意味着你会得到No such file or directory
错误。 - 分叉
grep
和这样的基本操作是愚蠢的。 特别是当你使用蹩脚的shell来避免bash的“沉重”的重量。 - 我也注意到了一些引用问题,例如围绕他的
echo
的参数扩展。 - 虽然很less见,但解决scheme无法处理包含换行符的文件名。 (在
sh
几乎没有解决scheme可以应付他们 – 这就是为什么我几乎总是喜欢bash
,它使用得当时更加防弹和更难以利用)。
虽然,使用/bin/sh
为你的hashbang意味着你必须不惜一切代价避免bash
isms,你可以使用所有你喜欢的bash
isms,甚至在Ubunutu上,或者当你诚实的时候使用#!/bin/bash
在顶部。
所以,这是一个更小,更干净,更透明,可能“更快”,更防弹的bash
解决scheme。
[[ -d $1 && $1 != *[^0-9]* ]] || { echo "Invalid input." >&2; exit 1; } rm -rf ~/foo/"$1"/bar ...
- 注意
rm
声明中的$1
左右的引号! - 如果
$1
为空,-d
检查也会失败,所以这是两个检查之一。 - 我避免了正则expression式的原因。 如果你必须在bash中使用
=~
,你应该把正则expression式放在一个variables中。 无论如何,像我这样的球体总是可取的,并且支持更多的bash版本。
我会用bash的[[
:
if [[ ! ("$#" == 1 && $1 =~ ^[0-9]+$ && -d $1) ]]; then echo 'Please pass a number that corresponds to a directory' exit 1 fi
我发现这个常见问题是一个很好的信息来源。
没有上面的答案那么简单,但是仍然有效:
#!/bin/bash if [ "$1" = "" ] then echo "Usage: $0 <id number to be cleaned up>" exit fi # rm commands go here
使用'-z'来testing空string,'-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
使用set -u
会导致任何未设置的参数引用立即使脚本失败。
http://www.davidpashley.com/articles/writing-robust-shell-scripts.html
testing的手册页( man test
)提供了所有可用的操作符,可以在bash中用作布尔运算符。 在你的脚本(或函数)的开始处使用这些标志来进行inputvalidation,就像你在任何其他编程语言中一样。 例如:
if [ -z $1 ] ; then echo "First parameter needed!" && exit 1; fi if [ -z $2 ] ; then echo "Second parameter needed!" && exit 2; fi
您可以通过执行如下操作来紧凑地validation点a和b:
#!/bin/sh MYVAL=$(echo ${1} | awk '/^[0-9]+$/') MYVAL=${MYVAL:?"Usage - testparms <number>"} echo ${MYVAL}
这给了我们…
$ ./testparams.sh Usage - testparms <number> $ ./testparams.sh 1234 1234 $ ./testparams.sh abcd Usage - testparms <number>
这个方法在sh中应该可以正常工作。
老post,但我想我可以贡献反正。
一个脚本可以说是没有必要的,并且可以从命令行执行一些对通配符的容忍。
-
野外任何地方匹配 让我们删除任何发生的“文件夹”
$ rm -rf ~/*/folder/*
-
壳迭代。 让我们用一行删除特定的前后文件夹
$ rm -rf ~/foo{1,2,3}/folder/{ab,cd,ef}
-
shell迭代+ var(BASHtesting)。
$ var=bar rm -rf ~/foo{1,2,3}/${var}/{ab,cd,ef}