简体   繁体   English

用bash替换'源文件'及其内容和扩展变量

[英]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 +vset -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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM