0

I am trying to run a series of commands on a remote server from a jenkins machine. Those commands do below stuff

  1. Create a directory on remote server
  2. Copy some files from remote server into that directory

I have created below script,

    servername=<remote server ip>

    sshuserconnect() {
        echo `/usr/bin/sshpass -p passwd ssh -o ConnectTimeout=5 -o UserKnownHostsFile=knownhosts -o StrictHostKeyChecking=no $*`
    }

sshuserconnect user@$servername << ENDOFSSH

    sqlplus -s /nolog << EOF > /home/user/output.txt
    connect user/pwd@$servername:<port>/<DB schema>
    select column1||','||value from table where column1 like 'param1';
    EOF

    version=`grep version /home/user/output.txt | cut -f 2 -d ","`
    mkdir /home/user/${version}

ENDOFSSH

Script fails with below error,

grep: output.txt: No such file or directory
Pseudo-terminal will not be allocated because stdin is not a terminal.

After some debugging I found out that script fails only for grep command. Assigning grep output to version variable fails.

I have tried lot of options and I am not if this is the correct way. Can anyone help me to resolve this?

user3347819
  • 209
  • 1
  • 2
  • 11
  • Yeah, this looks like a simple typo to me. Note that you can use awk instead of `grep | cut`: `awk -F, '/version/ { print $2 }' output.txt`. – Tom Fenech Jun 24 '16 at 18:05
  • Two suggestions, change output.txt to ./output.txt in case the local directory isn't part of your PATH. Also change ${Version} to ${version}. – LAROmega Jun 24 '16 at 18:06
  • @LAROmega, I have edited the question and changed the file path to absolute path. still error remains same. @TomFenech, I tried your approach as, `version='awk -F, '/version/ { print $2 }' /home/user/output.txt'`. still error is same. – user3347819 Jun 24 '16 at 18:34

1 Answers1

1

In your script expansion of `grep version ...` is performed by the local shell rather than by the remote shell. The same applies to the expansion of /home/user/${version}. Subtleties of using expansions in here-documents are covered in my answer to the canonical question addressing problems of this kind.

Your script belongs to the mixed case "3. Some expansions must be performed in the child shell, some - in the parent." discussed therein, and must be fixed as follows:

sshuserconnect user@$servername <<ENDOFSSH

sqlplus -s /nolog <<EOF > /home/user/output.txt
connect user/pwd@$servername:<port>/<DB schema>
select column1||','||value from table where column1 like 'param1';
EOF

version=\$(grep version /home/user/output.txt | cut -f 2 -d ",")
mkdir /home/user/\${version}

ENDOFSSH

Note that I intentionally removed the indentation of the script section inside the <<ENDOFSSH here-document, so that EOF is correctly recognized as the end-marker for the nested <<EOF here-document. There are two ways to preserve the indentation:

  1. Indent everything but the EOF end-marker:

    sshuserconnect user@$servername <<ENDOFSSH
    
        sqlplus -s /nolog <<EOF > /home/user/output.txt
        connect user/pwd@$servername:<port>/<DB schema>
        select column1||','||value from table where column1 like 'param1';
    EOF
    
        version=\$(grep version /home/user/output.txt | cut -f 2 -d ",")
        mkdir /home/user/\${version}
    
    ENDOFSSH
    

    This looks somewhat ugly.

  2. Indent with TABs rather than spaces, and use <<-ENDOFSSH instead of <<ENDOFSSH, which causes the leading tab characters in the here document to be removed. In the code below I purposefully marked the tab characters with <TAB>, both for explicitness and because StackOverflow renders tabs with spaces, meaning that copy&pasting the code would not work correctly:

    sshuserconnect user@$servername <<-ENDOFSSH
    
    <TAB>sqlplus -s /nolog <<EOF > /home/user/output.txt
    <TAB>connect user/pwd@$servername:<port>/<DB schema>
    <TAB>select column1||','||value from table where column1 like 'param1';
    <TAB>EOF
    
    <TAB>version=\$(grep version /home/user/output.txt | cut -f 2 -d ",")
    <TAB>mkdir /home/user/\${version}
    
    ENDOFSSH
    
Community
  • 1
  • 1
Leon
  • 31,443
  • 4
  • 72
  • 97
  • Good discussion, only nit is in *' Read this about'* the link `this` should be the *full title* (or at least a descriptive substring) of the article you are directing the user too. – David C. Rankin Jun 25 '16 at 07:31
  • @DavidC.Rankin Thanks for the suggestion. I updated the answer, though I couldn't find a good way of referring to the pointed-to question through its title. – Leon Jun 25 '16 at 07:50
  • Looks good, just something to make sure the users eyes don't skip over your link. Another trick is to **bold** the link. – David C. Rankin Jun 25 '16 at 08:03
  • Thanks Leon for your detailed answer. It gave me idea to rescript my work and avoid mistakes I was doing. I am able to run my script without errors now. – user3347819 Jun 25 '16 at 12:04