how to write a bash shell script to ssh to remote machine and change user and export a env variable and do other commands

18,353

Instead of connecting via ssh and then immediately changing users, can you not use something like ssh -t webservice_username@remotehost1 to connect with the desired username to begin with? That would avoid needing to sudo altogether.

If that isn't a possibility, try wrapping up all of the commands that you want to run in a shell script and store it on the remote machine. If you can get your task working from a script, then your ssh call becomes much simpler and should encounter fewer problems:

ssh myname@remotehost1 '/path/to/script'

For easily updating this script, you can write a short script for your local machine that uploads the most recent version via scp and then uses ssh to invoke it.

Share:
18,353
Peiti Li
Author by

Peiti Li

Updated on June 30, 2022

Comments

  • Peiti Li
    Peiti Li almost 2 years

    I have a webservice that runs on multiple different remote redhat machines. Whenever I want to update the service I will sync down the new webservice source code written in perl from a version control depot(I use perforce) and restart the service using that new synced down perl code. I think it is too boring to log to remote machines one by one and do that series of commands to restart the service one by one manully. So I wrote a bash script update.sh like below in order to "do it one time one place, update all machines". I will run this shell script in my local machine. But it seems that it won't work. It only execute the first command "sudo -u webservice_username -i" as I can tell from the command line in my local machine. (The code below only shows how it will update one of the remote webservice. The "export P4USER=myname" is for usage of perforce client)

    #!/bin/sh
        ssh myname@remotehost1 'sudo -u webservice_username -i ; export P4USER=myname; cd dir ; p4 sync ; cd bin ; ./prog --domain=config_file restart ; tail -f ../logs/service.log'
    

    Why I know the only first command is executed? Well because after I input the password for the ssh on my local machine, it shows:

    Your environment has been modified. Please check /tmp/webservice.env.
    

    And it just gets stuck there. I mean no return.

    As suggested by a commentor, I added "-t" for ssh

    #!/bin/sh
            ssh -t myname@remotehost1 'sudo -u webservice_username -i ; export P4USER=myname; cd dir ; p4 sync ; cd bin ; ./prog --domain=config_file restart ; tail -f ../logs/service.log'
    

    This would let the local commandline return. But it seems weird, it cannot cd to that "dir", it says "cd:dir: No such file or directory" it also says "p4: command not found". So it looks like the sudo -u command executes with no effect and the export command has either not executed or excuted with no effect.
    A detailed local log file is like below:

    Your environment has been modified. Please check /tmp/dir/.env.
    bash: line 0: cd: dir: No such file or directory
    bash: p4: command not found
    bash: line 0: cd: bin: No such file or directory
    bash: ./prog: No such file or directory
    tail: cannot open `../logs/service.log' for reading: No such file or directory
    tail: no files remaining
    
  • Peiti Li
    Peiti Li almost 12 years
    Is there any way to let the sudo -u command execute normally and let the rest commands execute ?
  • Nik
    Nik almost 12 years
    Not given what you're trying to accomplish; running multiple commands as a specific user in this case is just better done with a script. I checked the docs for sudo and couldn't find anything that would help.