Home > Blockchain >  Forcing string replacement in declared function of shell script
Forcing string replacement in declared function of shell script

Time:01-07

I'm working on a script to move some files to a remote server (see: Function calls in Here Document for unix shell script for more details). In order to allow the script to work both on a local machine and for a remote server, I'm using 'declare -f' to wrap an existing function to be executed remotely. So far I have come up with this:

myscript.sh

REMOTE_HOST=myhost
TMP=eyerep-files

getMoveCommand()
{
    echo Src Dir: $2
    sudo cp ~/$TMP/start.ini ~/$1/start_b.ini
    
    ls ~/$2
    echo Target Dir: $1
    ls ~/$1
}

moveRemote()
{
    echo "attempting move with here doc"
    echo $(declare -fp getMoveCommand ) 
    ssh -t "$REMOTE_HOST" "$(declare -fp getMoveCommand); getMoveCommand ${1@Q} ${TMP@Q}"
}

moveFiles()
{   
        case "$1" in
      # remote deploy
      remote)
        moveRemote $2
        ;;
      # local deploy
      local)
        getMoveCommand $2
        ;;
      *)
        echo "Usage: myscript.sh {local|remote}"
        exit 1
        ;;
    esac
    
}

moveFiles $1 $2
exit 0

If called with './myscript.sh remote dev' the script should ssh into the remote server and move a file from one folder to another. The problem I'm running into is the string replacement. I have a bunch of global variables acting as constants that getMoveCommand needs access to. In the example here there is only one (TMP) so I can simply pass it as an argument. In the actual script however, the work being done is more complicated and the number of arguments that would need to be passed in would make this solution unwieldy. Since those variables are never expected to change, it seems like it should be possible to force the string replacement to occur before sending the wrapped function along to ssh.

Is what I want to do possible, and if so how? If not, is there another way to handle this that doesn't require passing a large number of arguments to the function?

CodePudding user response:

You can also send global variables using declare -p:

ssh -t "$REMOTE_HOST" "$(declare -fp getMoveCommand; declare -p GLOBAL_VAR_1 GLOBAL_VAR_2)"$'\n'"getMoveCommand ${1@Q} ${TMP@Q}"

You can also have another global variable that declares them so you can expand them easily:

GLOBAL_VARS=(GLOBAL_VAR_1 GLOBAL_VAR_2)
...
ssh -t "$REMOTE_HOST" "$(declare -fp getMoveCommand; declare -p "${GLOBAL_VARS[@]}")"$'\n'"getMoveCommand ${1@Q} ${TMP@Q}"

If your variables have a common prefix, you can also expand them through "${!PREFIX@}". No need to store to a variable.

Or might as well create an "export" function to keep things cleaner:

dump_env() {
    declare -fp getMoveCommand
    declare -p GLOBAL_VAR_1 GLOBAL_VAR_2
}
...
ssh -t "$REMOTE_HOST" "$(dump_env)"$'\n'"getMoveCommand ${1@Q} ${TMP@Q}"

CodePudding user response:

It is possible to use envsubst if you export the variable:

export TMP=foo

getMoveCommand() {
        echo TMP is $TMP
}

declare -fp getMoveCommand|envsubst

The script above prints:

getMoveCommand () 
{ 
    echo TMP is foo
}
  •  Tags:  
  • Related