Replacing 'source file' with its content, and expanding variables, in bash

点点圈 提交于 2020-12-08 07:55:09

问题


In a 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)? I would like to see what the bash interpreter executes after sourcing the files and expanding all variables.

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).

I thought of using a subshell, but that still doesn't expand the source lines. I tried a combination of set +n +v and set -n -v before and after the source lines, but that still does not work.

I'm going to send that output to a remote machine using 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. 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'

Is there a solution? Or do you have a better idea?


回答1:


You can do something like this:

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 sourced files exist, and doesn't handle errors. You should also handle possible hashbangs. If the sourced files contain themselves source, you need to apply the script recursively, e.g. something like (not tested):

while egrep -q '^(source|\.)' main.sh; do
    bash inline.sh main.sh > main.sh
done

Let's test it

main.sh:

source a.sh
. b.sh

echo cc
echo "$var_a $var_b"

a.sh:

echo aa
var_a="stack" 

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 -x [script]

or remotely

ssh user@host -t "bash -x [script]"


来源:https://stackoverflow.com/questions/37531927/replacing-source-file-with-its-content-and-expanding-variables-in-bash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!