我有一个bash脚本来跨多个目录运行命令。当这样调用时,它可以正常工作:
$ ./run git status
但是,引用该子命令时,出现“找不到命令”错误。
$ ./run "git status"
这将我限制为只能传递一个命令来运行,而不是理想情况,例如:
$ ./run "git status && npm install"
跑步
#!/bin/bash
paths="/Users/guy/project /Users/guy/project-2"
for i in $paths; do
(cd "$i" && "$@")
done
您的run
命令可能希望执行的命令与要评估的Shell代码相对(要发布的命令,现在进行编辑:是的,确实是,那是"$@"
)
如果该run
命令实际上是Shell脚本,则它可能会接受诸如eval
(edit:是,确实如此)之类的内置命令,在这种情况下,您应该能够执行以下操作:
./run eval 'git status && npm install'
(该代码将在run
脚本的上下文中进行评估,如果它修改了脚本内部的某些变量(例如./run eval 'PATH=/none; ...'
),可能会产生意想不到的效果(编辑:此处不是,因为这是在subshell中运行的最后一个命令))。
如果没有,您总是可以告诉它运行一个shell来评估该shell代码:
./run sh -c 'git status && npm install'
在这里,我还将使用数组变量来存储路径列表,而不是将其存储在标量变量中,而是依靠split + glob运算符对其进行拆分。您可能还想报告退出状态中的失败
#!/bin/bash -
paths=(/Users/guy/project /Users/guy/project-2)
ret=0
for i in "${paths[@]}"; do
(cd -P -- "$i" && "$@") || ret=$?
done
exit "$ret"
如果要让脚本代替接受外壳程序代码,则可以执行以下操作:
#!/bin/bash -
paths=(/Users/guy/project /Users/guy/project-2)
ret=0
for i in "${paths[@]}"; do
(cd -P -- "$i" && eval "$@") || ret=$?
done
exit "$ret"
但我建议不要这样做,因为用户可能会喜欢做以下事情:
./run git add "$file"
这将是一个隐藏命令注入漏洞(当象$file
是foo;reboot
)。
./run eval "git add $file"
将是相同的命令注入漏洞,但至少不会被用户隐藏。
对于它来说,它不是一个命令注入漏洞,而run
没有使用eval
:
./run git add "$file"
或使用eval
,但使用静态代码,并通过环境变量传递动态值。
FILE=$file ./run eval 'git add "$FILE" && git commit -m blah'
或使用sh -c
但带有静态代码并通过参数传递动态值。
./run sh -c 'git add "$1" && git commit -m blah' sh "$file"
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句