从tcsh别名向bash脚本传参异常,如何解决?
解决tcsh别名传递参数到bash脚本时的参数异常问题
问题场景
我在bash脚本savall2all.bash末尾仅保留一行测试代码:
echo "$# args: $@ passed to bash script"
接着在~/.tcshrc中定义调用该脚本的别名:
alias savall2all 'bash $BACKUP/savall2all.bash \!*'
在tcsh环境中执行命令时,明明传入两个路径参数:
echo $RST > /Users/My/Documents/DESK/DESK_N2R/RST echo $HST > /Users/My/Documents/DESK/DESK_E2M/HST savall2all $RST $HST
但bash脚本的输出却显示仅收到1个无关的环境变量参数:
> 1 args: SD02FL=/Volumes/SuperDuper-02-Files passed to bash script
问题原因
tcsh中,\!*属于历史替换语法,作用是引用上一条执行命令的所有参数,而非当前别名调用时传入的参数。之前的别名写法错误地使用了\!*,导致bash收到的是上一条命令的参数(恰好是SD02FL相关内容),而非当前传入的$RST和$HST。
另外,$BACKUP未加引号,如果其路径包含空格,会被tcsh拆分成多个部分,导致bash无法正确识别脚本路径。
解决方案
1. 修正tcsh别名的参数传递语法
将~/.tcshrc中的别名修改为:
alias savall2all 'bash "$BACKUP/savall2all.bash" \!:*'
- 使用
\!:*替代\!*:这是tcsh别名中获取当前调用时所有参数的正确语法 - 给
"$BACKUP/savall2all.bash"添加双引号:避免路径含空格时被拆分
2. 调用别名时正确传递参数
如果$RST或$HST的路径包含空格,调用时需用双引号包裹变量,防止参数被拆分:
savall2all "$RST" "$HST"
验证效果
修改后重新执行命令,bash脚本应输出:
2 args: /Users/My/Documents/DESK/DESK_N2R/RST /Users/My/Documents/DESK/DESK_E2M/HST passed to bash script
内容的提问来源于stack exchange,提问作者David Sieving
相关产品推荐
相关产品推荐

