0

How can I pass a variable between scripts?

Example: I have two test scripts:

-- test2.sh
#!/bin/bash
echo "this is test2.sh"
echo "varname is $varname"
echo end

-- tes1.sh
#!/bin/bash 
varname="123456"
ssh user@111.222.333.444 
"bash" < varname=$varname test2.sh

The idea is that I run test1.sh which connects to a remote server, and executes test2.sh. But all I am getting is varName is 123456: No such file or directory

  • well spotted. . . that was a typo – IGGt Dec 9 '15 at 15:48
  • Do you have a copy of test2.sh locally? – Eric Renouf Dec 9 '15 at 15:50
  • test1.sh and test2.sh exist only on the main server, However, test2.sh contains code that connects to a database and runs some queries. The varname variable(s) will contain database connection details amongst others. – IGGt Dec 9 '15 at 15:54
2

You're running into an "order of operations" type problem I think. The < is processed before the commands are execute, so you're running something similar (though not identical to)

varname=$varname test2.sh | ssh user@111.222.333.444 bash

which runs the test2.sh locally, then sends that output to bash on the remote server. That's why you see the output of test2.sh but then get an error when it tries to execute that output as a command.

If you're running a script that's executable you don't really need the bash there though, so you could just do

ssh user@111.222.333.444 "varname=$varname ./test2.sh"

assuming test2.sh is available on the remote server.

If you don't have test2.sh on the remote server and still want to execute it there you could do it like so:

ssh user@111.222.333.444 varname="$varname" bash < test2.sh

which will redirect the script source but do the variable processing in the context of the bash executable

  • that's closer cheers, but not quite. I am just getting varname is with no numbers. – IGGt Dec 9 '15 at 16:06
  • Hmm, and you're sure you have the same capitalization on varname still, right? Because when I test this execution with a simple script I'm getting the value printed on the other side – Eric Renouf Dec 9 '15 at 16:13
  • it is. I added echo test1 varname is $varname to test1.sh just to make sure it was being set properly, and that works fine. It just doesn't copy across. – IGGt Dec 9 '15 at 16:17
  • Ah ha, in test2.sh I still had varname is $1 instead of varname is $varname. It now works. Cheers for your help, – IGGt Dec 9 '15 at 16:19
3

Why don't you just pass it as an argument. ie.

test2.sh

#!/bin/bash
echo "this is test2.sh"
echo "varName is $1"
echo end

test1.sh

#!/bin/bash 
varName="123456"
scp test2.sh user@111.222.333.444:/tmp/
ssh user@111.222.333.444 "/tmp/test2.sh $varName"
ssh user@111.222.333.444 "rm -f /tmp/test2.sh"
  • cheers, by that gives me bash: test2.sh: command not found – IGGt Dec 9 '15 at 15:54
  • Is test2.sh located on the local machine or the remote one? – David King Dec 9 '15 at 15:56
  • the local machine (same place as test1.sh) – IGGt Dec 9 '15 at 15:57
  • If you want to run test2.sh on the remote machine it should be located there. – David King Dec 9 '15 at 16:06
  • The problem is that there is apx 70 machines to run it on, and as the script is the same for all of them I don't want to try and maintain 70 copies of it. – IGGt Dec 9 '15 at 16:08
0

To define a process's environment on the command-line you need to order your definitions before the command:

varname=$varname bash < $varname test1.sh

It also seems unlikely to me that you really want to open a file named...

varname=${expansion_of_varname}

though that appears to be what you are trying to do. I expect that will cause issues as well. If you want every variable assignment to affect the environment of all of the shell's children, then you can do:

set -a

...first. (though even then x=; <${x:=file} sh -c 'echo "$x"' still doesn't appear to work without an intervening semicolon).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.