自己写Shell脚本时,时常需要处理的一个操作是,如果用户没有提高输入参数,我们该如何判断输入非空和设定默认值呢?这就要依赖我之前写过的条件判断命令和字符串判断选项-n
或-z
了。
用一个实际例子,我写过一个命令集(其实就是几个脚本)【sync deploy】利用ssh
将本地命令在远程执行,而不需要显式地进行远程登录、处理、退回等一系列操作。以其中一个脚本sync-run
作为解释:
#!/bin/bash
# run work task script on remote server
while getopts :f:ht opt
do case "$opt" in
f) fl=$OPTARG ;;
h) echo
echo "Usage: sync-run -f work_script -t"
echo "==> work_script: script used to run on remote, must be a shell script contains qsub_header."
echo "==> You can use relative/absolute file path on server file system."
echo "==> if -t option specified, the command will run as batch mode, it usually called by sync-deploy command."
echo "==>"
echo "==> examples:"
echo " sync-run -f work.sh # this is regular mode, basically you wanna this if you run this script independently"
echo " or"
echo " sync-run -n work.sh -t # this is batch mode, basically used to be called by sync-deploy command"
echo " # it will additionally generate a job_id file in the same directory as work_script"
echo
exit ;;
t) batch="y" ;;
*) echo "Unknown option: $opt"
echo
sync-run -h
exit ;;
esac
done
# Get setting info
#source "$(pwd)/syn-setting"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$DIR/syn-setting"
# if variable port is not set, set 22 as default
if [ ! -n "$port" ]; then
port=22
fi
if [ ! -n "$batch" ]; then
batch="n"
fi
# you can also use absolute path
if [ $batch == "y" ]; then
echo "==> run as batch mode......."
ssh -p $port $remote_user@$remote_ip "qsub $fl >> $(dirname $fl)/job_id; echo 'job id is'; cat $(dirname $fl)/job_id; rm $(dirname $fl)/job_id"
else
echo "==> run as regular mode......."
ssh -p $port $remote_user@$remote_ip "qsub $fl"
fi
这里不需要关注脚本细节,只需要查看整体结构,分以下几个部分:
- 构建命令选项
- 根据命令选项参数构建命令需要使用的参数,如果有输入提供,则使用输入,否则使用默认值
- 根据参数运行命令
其中第二个部分是这篇文章关注点,其中代码
# if variable port is not set, set 22 as default
if [ ! -n "$port" ]; then
port=22
fi
提供了一个范例:如果用户输入没有指定端口,则使用默认端口22。这里使用了
if [ ! -n "$port" ]
来检查是否用户输入了端口参数,其实就是判断下$port
存储的字符串是否非空。因此这部分的实质就是个字符串检测与判断的问题。
-n
选项检查字符串是否非空,那么加个!
即可表示无输入。另一个选项-z
可以直接判断字符串是否空,更简便些。
下面代码即为证明:
[root@linuxprobe Desktop]# [ -z $fds ]
[root@linuxprobe Desktop]# echo $?
0
[root@linuxprobe Desktop]# [ ! -n $fds ]
[root@linuxprobe Desktop]# echo $?
1