You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bash管道(cat/wget | bash)中传递脚本参数

管道执行Bash脚本时传递参数的正确姿势

这个问题我太熟了!管道执行脚本(比如cat script.sh | bash或者wget ... | bash)和直接执行脚本的参数传递逻辑确实不一样——直接执行时参数是传给脚本本身的,但管道模式下bash是从标准输入读脚本内容,默认不会把命令行参数递交给脚本。不过用bash -s选项就能完美解决,这也是nvm安装脚本采用的核心方法。

核心解法:用bash -s让参数流向脚本

当你通过管道把脚本内容传给bash时,加上-s选项,bash就会把后续的命令行参数当成脚本的位置参数(也就是$1、$2这类变量),而不是bash自身的命令选项。

拿你的test.sh举例子:

#!/usr/bin/env bash
echo $1
echo "execution done"

原来的管道执行方式cat test.sh | bash "started"会失败,因为"started"会被bash当成要执行的文件名,而非脚本参数。改成下面的命令就完全正常了:

cat test.sh | bash -s "started"

执行后输出和直接执行一致:

started
execution done

处理带-开头的特殊参数

如果你的参数是以-开头的(比如-v、--help),为了避免bash把它们误判成自身的命令选项,需要用--来分隔bash选项和脚本参数:

cat test.sh | bash -s -- -v

这样脚本里的$1就能准确拿到-v,不会被bash拦截。

结合bash自身选项的场景

如果需要给bash加自身的选项(比如-x开启调试模式),把bash的选项放在-s前面即可:

cat test.sh | bash -x -s "started"

这样bash会先开启调试输出,同时把"started"正常传给脚本作为$1。

多参数传递

传递多个参数也很简单,直接在-s后面依次列出就行:

cat test.sh | bash -s "first arg" "second arg"

脚本里的$1会是first arg,$2会是second arg,和直接执行脚本的参数逻辑完全一致。

为什么nvm安装脚本这么写?

nvm的安装命令(比如curl ... | bash -s -- --version)就是用了这个逻辑:-s告诉bash从标准输入读取安装脚本,--用来明确分隔bash选项和脚本参数,后面的--version就是传给安装脚本的指令,让脚本执行特定的版本查询逻辑。

内容的提问来源于stack exchange,提问作者Vipin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:37:34