shell编程技巧

Posted by BenderFly on April 4, 2019

如何简化if else?

somecommand
if [ $? -ne 0 ]; then
  echo "command failed."
  exit 1
fi

简化的一个方法是,首先写一个die函数:

function die
{
  echo $@
  exit 1
}

然后,上面的if就可以改写为

somecommand || die "Command failed."

类似的,如果要检查某个变量var有没有设置,如果没有设置就退出,可以写成:

[ -z $var ] && die "environment variable var is not set"

如何判断某个字符串是不是以特定字符串开始

var="# this is comments"
[[ $var == "#"* ]] && echo "line starts with # is ignored."

如何取得当前脚本的名字? 

declare me=basename $0 这样在脚本中需要用到当前脚本名字的地方用$me来代替,比如usage信息的时候。

如何取得当前脚本所在的目录?

declare parent_dir=$(dirname $(readlink -f $0))

如何取得当前用户的用户名

declare current_user=$(id -un)

如何取得当前用户的home目录

declare current_user_home=$(dirname ~)/basename ~ 不知道为什么,脚本中直接用~来表示当前用户的home目录不行。所以只好用这种办法了。

如何定义常量?

readonly version=”V1.0”

Bash中支持指针吗?

支持。 假设current_user=jewes,同时定义var=current_user,${!var}的值就是jewes。它先对var求值,然后将var的值作为一个变量再求值。

如何判定一个目录是否为空?

if [[ "$(ls -A $WSPACE_ROOT/$wspacename)" ]]; then
  echo "folder not empty"
fi

如何提示输入密码并在屏幕上显示为*

function enter_password()
{
  local prompt=$1 # prompt message
  unset user_typed_password
  while IFS= read -p "$prompt" -r -s -n 1 char
  do
    if [[ $char == $'\0' ]]; then
      break
    fi
    prompt='*'
    user_typed_password+="$char"
   done
  echo ""         # force a carriage return to be output
}

enter_password "Tell me your bank account password:"

其中,密码将被保存到user_typed_password,调用这个方法后就可以从其中取得用户输入的密码。

如何记录某台命令执行了多长时间?

starttime=$(date +%s)
# some time consuming command
endtime=$(date +%s)
timediff=$(( $endtime - $starttime ))
timediff中保存的是两个时间差,以秒为单位。

在ssh到远程机器的时候,如何自动接受远程机器的HostKey?

如果你第一次ssh到远程机器,ssh会提示你是否接收远程机器的Key。在脚本环境下,它可能会使你的脚本停下来。可以在ssh的时候指定下面两个参数:

 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null 第一个参数是让ssh自动接受远程机器的key,后面一个参数是不让其保存默认的knownhosts文件中,这主要是避免远程机器改变了key,脚本就又不工作了。