bash shell: 避免使用别名来解释 $!
bash shell: Avoid alias to interpret $!
我创建了一个别名:
alias my_rsync = "rsync -av ${PATH_EXCLUDE_DEV} ${PATH_SYS_DEV}/` ${PATH_SYS_SANDBOX}/ && wait $! && cd - &>/dev/null\"
什么时候加载这个别名并用命令观察它 'type 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"
你们能给我点提示吗?谢谢
如果您不想解释某个变量,请将其转义或使用单引号。
示例:
$ alias x="false; echo $?"
$ x
0
$ alias x='false; echo $?'
$ x
1
使用函数,而不是别名,您可以完全避免这种情况。
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
}
这运行在后台同时进行多个rsync(每个主机一个),将它们的PID存储在一个数组中,然后在它们都存在时遍历该数组运行 让他们完成。
值得注意的是,正是 单个 &
运算符 导致 rsync
在后台变为 运行。如果它们用 &&
、;
或换行符与以下命令分开,它们将一次 运行 一个,而 $!
的值永远不会是改变了。
我创建了一个别名:
alias my_rsync = "rsync -av ${PATH_EXCLUDE_DEV} ${PATH_SYS_DEV}/` ${PATH_SYS_SANDBOX}/ && wait $! && cd - &>/dev/null\"
什么时候加载这个别名并用命令观察它 'type 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"
你们能给我点提示吗?谢谢
如果您不想解释某个变量,请将其转义或使用单引号。
示例:
$ alias x="false; echo $?"
$ x
0
$ alias x='false; echo $?'
$ x
1
使用函数,而不是别名,您可以完全避免这种情况。
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
}
这运行在后台同时进行多个rsync(每个主机一个),将它们的PID存储在一个数组中,然后在它们都存在时遍历该数组运行 让他们完成。
值得注意的是,正是 单个 &
运算符 导致 rsync
在后台变为 运行。如果它们用 &&
、;
或换行符与以下命令分开,它们将一次 运行 一个,而 $!
的值永远不会是改变了。