1

Here is my script:

cmd=(''' ssh $servername /usr/local/bin/pstat $1|awk 'FNR==5 {print $9}' %s ''' %int(var))  
p=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
out, err=p.communicate()  
print "err", err 

Here is the error:

err awk: cmd. line:1: fatal: cannot open file (No such file or directory)

I believe I am not writing cmd properly. What am I missing?

  • What would the cmd string, tuple, whatever, be when you use it in Popen()? I'm not a Python programmer. – Kusalananda Jul 10 '18 at 17:40
  • cmd output from shell command should be job submission time in the form of HH:MM:SS – Akand Jul 10 '18 at 17:51
  • I asked about what actually got executed, not what the output of it would be. – Kusalananda Jul 10 '18 at 18:15
  • When I print output ("out"), doesn't show anything. – Akand Jul 10 '18 at 19:11
  • Sure, but what is actually the value of cmd? – Kusalananda Jul 10 '18 at 19:11
0

The command you have the shell run is something like this, with 1234 being a value from var (this is passed as argument to sh -c):

ssh $servername /usr/local/bin/pstat $1|awk 'FNR==5 {print $9}' 1234

There, $1 is expanded into the first argument of the shell, but it doesn't have have any, so that disappears. 1234 is an argument to awk, which takes it as the name of an input file, tries to open it and fails.

I'm assuming you want the value from var as an argument to pstat instead. You have two options: either place the number where you have $1 now, with %s as you did above; or use $1, and pass var as an argument to the shell that Popen runs.

With %s:

cmd=(''' ssh "$servername" /usr/local/bin/pstat '%s' | awk 'FNR==5 {print $9}' '''
      % int(var))  
p=subprocess.Popen(cmd, shell=True,  ... )

Note that this drops the variable value in the middle of the shell command, so you do need to know it doesn't contain anything dangerous. With single-quotes around it, only single-quotes will cause issues. Since you only have a number, this should be safe.

With $1:

cmd=(''' ssh "$servername" /usr/local/bin/pstat "$1" | awk 'FNR==5 {print $9}' ''')  
p=subprocess.Popen([cmd, "sh", str(var)], shell=True,  ... )

Here, we pass an array as the first argument of Popen, which makes it use the first array element as the command line, and the rest as arguments to the shell. (i.e. it runs sh with the arguments -c, cmdline..., sh and 1234. The sh string goes to the shell's $0.)

This is safer than the previous in that variable value is never mixed with the code the shell runs (but note that you need the double quotes around "$1" for the usual reasons).

Note that you need to have servername set in the environment for that variable to be expanded by the shell Popen runs.

  • Thanks! They work fine. One clarification, when I execute the command in cmd from a separate "cmd.sh" file and then calling as commands.getoutput(" ./cmd %s" %(var)), works fine. The "cmd.sh" file contains ssh $servername /usr/local/bin/pstat $1 | awk 'FNR==5 {print $9}'. Why in this case the awk doesn't show problem? – Akand Jul 11 '18 at 13:53
  • @Akand, You're passing one argument to the script ./cmd.sh, it then shows up as $1 within the script. In the script, you also have only one argument to awk (the string in single quotes), not two as in your question. The arguments to the script and the arguments to a command within the script are different. – ilkkachu Jul 11 '18 at 18:51

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.