Ryan
Ryan

Reputation: 63

this BASH code works on a command line, but not when i move it into a script

I built-up a kludgey script on the CLI that I can't successfully move into a text file. I know it's poorly-written, but I'm interested in resolving the problem I'm having, not re-writing it. I want to understand why my poorly-written code behaves differently when executed on the command line compared to when it's saved as a file.

I think it's related to something getting interpolated prematurely in the script, because if I substitute the one-liner version into the same file (without formatting) I get identical output. Note the debug line below and how it doesn't print.

CONTENTS OF SCRIPT

#!/bin/bash

totalNodes=0             #initialize sum                                                                                     
echo -e "ID\t\t\tNODES"; #title line                                                                                         
for n2 in $(             #n2 will get populated with the number of nodes (to be added to totalNodes)                         
    for n in $(          #n is an intermediate string that munges the Resource_list.nodes line (kludgy)                      
        for i in $(
            qstat|grep " ef "|cut -f 1 -d ' ')     #i gets the ef queue lines                                                
        do
            echo "debug $i"
            j=$(echo $i|sed 's/(\d+)\..+/\$1/');    #j is the actual ID                                                      
            qstat -f | grep -A43 $j;               #extracts the full output from qstat for this job ID                      
        done|grep Resource_List.nodes)             #closes definition of n over loop                                         
    do echo ${n};done|grep ppn)                    #closes definition of n2 over loop                                        
do
   echo "$j ${n2:0:1}"                             #output line                                                              
   totalNodes=$(($totalNodes+${n2:0:1}))           #counting nodes                                                           
done
echo "$totalNodes nodes of 16 running in EF queue"

EXPECTED OUTPUT (what I get at the command line):

ID          NODES
2378512.yaddayadday-adm 4
2378512.yaddayadday-adm 4
2378512.yaddayadday-adm 4
2378512.yaddayadday-adm 2
14 nodes of 16 running in EF queue

CURRENT OUTPUT from the script

ID          NODES
 4
 4
 4
 2
14 nodes of 16 running in EF queue

So I'm confused how I can get the right total (meaning $n2 is getting defined correctly) but I can't even print $i on the debug-with-print line (line 8.)

For reference, here's the one-liner. Like I said, this gives the "EXPECTED OUTPUT" shown above, when executed on the command line, but the same output as the above codeblock "CONTENTS OF SCRIPT" when I save it as a file with no additional formatting.

totalNodes=0;echo -e "ID\t\t\tNODES";for n2 in $(for n in $(for i in $(qstat|grep " ef "|cut -f 1 -d ' ');do j=$(echo $i|sed 's/(\d+)\..+/$1/');qstat -f | grep -A43 $j;done|grep Resource_List.nodes);do echo ${n};done|grep ppn);do echo "$j ${n2:0:1}";totalNodes=$(($totalNodes+${n2:0:1})); done;echo "$totalNodes nodes of 16 running in EF queue"

Upvotes: 1

Views: 610

Answers (2)

michael501
michael501

Reputation: 1482

several bugs :

1- qstat|grep " ef "|cut -f 1 -d ' ' is returning an empty list

2- qstat -f | grep -A43 $j is returning en empty list

before running the loop make sure #1 and #2 generates a valid list

since qstat|grep " ef "|cut -f 1 -d ' ' is constant , consider moving it outside the loops

$x1 = $(qstat|grep " ef "|cut -f 1 -d ' ')

use $x1 instead of above

Upvotes: 0

konsolebox
konsolebox

Reputation: 75568

Command substitution method $() runs commands in it on a subshell so if you define a variable inside it the value of that variable would be lost outside.

j=1
: "$(j=2)"
echo "$j" # => 1

Upvotes: 4

Related Questions