[英]Replacing 'source file' with its content, and expanding variables, in bash
In a script.sh, 在script.sh中,
source a.sh
source b.sh
CMD1
CMD2
CMD3
how can I replace the source *.sh
with their content (without executing the commands)? 如何将source *.sh
替换为其内容(不执行命令)? I would like to see what the bash interpreter executes after sourcing the files and expanding all variables. 我想看看在获取文件和扩展所有变量后bash解释器执行了什么。
I know I can use set -n -v
or run bash -n -v script.sh 2>output.sh
, but that would not replace the source commands (and even less if a.sh or b.sh contain variables). 我知道我可以使用set -n -v
或运行bash -n -v script.sh 2>output.sh
,但这不会替换源命令(如果a.sh或b.sh包含变量,则更少)。
I thought of using a subshell, but that still doesn't expand the source lines. 我想过使用子shell,但仍然没有扩展源代码行。 I tried a combination of set +n +v
and set -n -v
before and after the source lines, but that still does not work. 我在源代码行之前和之后尝试了set +n +v
和set -n -v
的组合,但这仍然不起作用。
I'm going to send that output to a remote machine using ssh. 我将使用ssh将该输出发送到远程计算机。 I could use <<output.sh
to pipe the content into the ssh command, but I can't log as root onto the remote machine, but I am however a sudoer. 我可以使用<<output.sh
将内容<<output.sh
给ssh命令,但我无法以root用户身份登录到远程计算机上,但我却是一个sudoer。 Therefore, I thought I could create the script and send it as a base64-encoded string (using that clever trick ) base64 script | ssh remotehost 'base64 -d | sudo bash'
因此,我以为我可以创建脚本并将其作为base64编码的字符串发送(使用那个聪明的技巧 ) base64 script | ssh remotehost 'base64 -d | sudo bash'
base64 script | ssh remotehost 'base64 -d | sudo bash'
Is there a solution? 有解决方案吗? Or do you have a better idea? 或者你有更好的主意吗?
You can do something like this: 你可以这样做:
inline.sh: inline.sh:
#!/usr/bin/env bash
while read line; do
if [[ "$line" =~ (\.|source)\s+.+ ]]; then
file="$(echo $line | cut -d' ' -f2)"
echo "$(cat $file)"
else
echo "$line"
fi
done < "$1"
Note this assumes the source
d files exist, and doesn't handle errors. 请注意,这假定source
d文件存在,并且不处理错误。 You should also handle possible hashbangs. 您还应该处理可能的hashbang。 If the sourced
files contain themselves source
, you need to apply the script recursively, eg something like (not tested): 如果sourced
文件包含自己的source
,则需要递归地应用脚本,例如(未测试):
while egrep -q '^(source|\.)' main.sh; do
bash inline.sh main.sh > main.sh
done
Let's test it 我们来试试吧
main.sh: main.sh:
source a.sh
. b.sh
echo cc
echo "$var_a $var_b"
a.sh: 灰:
echo aa
var_a="stack"
b.sh: b.sh:
echo bb
var_b="overflow"
Result: 结果:
bash inline.sh main.sh
echo aa
var_a="stack"
echo bb
var_b="overflow"
echo cc
echo "$var_a $var_b"
bash inline.sh main.sh | bash
aa
bb
cc
stack overflow
BTW, if you just want to see what bash executes, you can run 顺便说一句,如果你只是想看看bash执行什么,你可以运行
bash -x [script]
or remotely 或远程
ssh user@host -t "bash -x [script]"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.