bash shell:避免使用别名来解释$!

时间:2015-06-09 15:52:54

标签: bash shell alias wait

我创建了一个别名:

alias my_rsync = "rsync -av ${PATH_EXCLUDE_DEV} ${PATH_SYS_DEV}/` ${PATH_SYS_SANDBOX}/ && wait $! && cd - &>/dev/null\"

何时加载此别名并使用命令'输入my_rsync'我看到了$!已经消失,因为它已被解释。

通常情况下,我会使用反斜杠进行转义,但它确实运行良好。例如:

alias my_rsync = "mysql ${DB_DATA_SYS_SANDBOX} -e 'SHOW TABLES' | grep -v 'Tables_in_${DB_NAME_SANDBOX}' | while read a; do mysql ${DB_DATA_SYS_SANDBOX} -e \"DROP TABLE \$a\";done"
你能给我一个提示吗?感谢。

2 个答案:

答案 0 :(得分:3)

使用函数而不是别名,并且完全避免使用它。

my_rsync() {
  # BTW, this is horrible quoting; run your code through http://shellcheck.net/.
  # Also, all-caps variable names are bad form except for specific reserved classes.
  rsync -av ${PATH_EXCLUDE_DEV} ${PATH_SYS_DEV}/ ${PATH_SYS_SANDBOX}/ &>/dev/null
  cd -
}

...在这个公式中,在扩展函数之前不会发生任何扩展。

至于wait - 当你在后台运行时,它才有意义。您在此处使用的内容并非在后台启动任何内容,因此wait调用没有任何意义。

另一方面,以下显示目的的一些等待呼叫:

rsync_args=( --exclude='/dev/*' --exclude='/sys/*' )
hosts=( foo.example.com bar.example.com )

my_rsync() {
  # declare local variables
  declare -a pids=( ) # array to hold PIDs
  declare host pid    # scalar variables to hold items being iterated over

  for host in "${hosts[@]}"; do
    rsync -av "${rsync_args[@]}" /sandbox "$host":/path & pids+=( "$!" )
  done

  for pid in "${pids[@]}"; do
    wait "$pid"
  done
}

它在后台同时运行多个rsyncs(每个主机一个),将它们的PID存储在一个数组中,然后在它们全部运行时遍历该数组以让它们完成。

值得注意的是,&运算符导致rsync s在后台运行。如果使用&&;或换行符将它们与以下命令分开,则它们将一次运行一个,$!的值永远不会更改。

答案 1 :(得分:0)

如果您不想解释变量,请将其转义或使用单引号。

示例:

$ alias x="false; echo $?"
$ x
0

$ alias x='false; echo $?'
$ x
1