本文介绍了这BASH code工作在命令行上,而不是当我把它移动到一个脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建成的CLI一kludgey脚本,我不能成功移动到一个文本文件。 我知道它写得不好,但我感兴趣的是解决我遇到的问题,而不是重新写它。我想知道为什么我写得不好code具有不同的行为时,在命令行上执行时相比,它保存为一个文件。

我认为这是相关的东西越来越插值prematurely在脚本中,因为如果我代替单行版本到同一个文件(不带格式)我得到相同的输出。注意下面的调试线,以及它如何不打印。

SCRIPT目录


#!/斌/庆典totalNodes = 0 #initialize总和
回声-eID \\ t \\ t \\ tNODES #title线
对于在$ N2(#N2将得到填充节点的数目(将被加入到totalNodes)
    对于n $中(#N是一个中间字符串,munges的Resource_list.nodes线(缺憾)
        因为我在$(
            qstat命令| grep的EF|切-f 1 -d'')#我得到EF队列线
        做
            回声调试$ I
            J = $(回声$ I | sed的'S /(\\ d +)\\ .. + / \\ $ 1 /'); #j中是实际ID
            参阅qstat -f | grep的-A43 $焦耳; #extracts从qstat命令的全部输出这份工作ID
        做| grep的Resource_List.nodes)#closesñ在循环的定义
    做回声$ {N};完成| grep的PPN)#closes N2在循环的定义

   回声附加$ J $ {N2:0:1}#output线
   totalNodes = $(($ totalNodes + $ {N2:0:1}))#counting节点
DONE
回声16 $ totalNodes节点EF队列运行

期望的输出(我所得到的在命令行):


ID NODES
2378512.yaddayadday-ADM 4
2378512.yaddayadday-ADM 4
2378512.yaddayadday-ADM 4
2378512.yaddayadday-ADM 2
16的14个节点在EF队列运行

电流输出从剧本


ID NODES
 4
 4
 4
 2
16的14个节点在EF队列运行

所以我很困惑我怎么能得到正确的总额(即$ N2是得到正确定义),但我甚至无法打印$我在调试与打印线(8号线)。

有关参考,这里是单行。就像我说的,这给了预期的输出如上图所示,当在命令行中执行,但在相同的输出上面codeblock将SCRIPT的内容当我把它保存为一个文件,没有额外的格式化。


totalNodes = 0;回声-eID \\ t \\ t \\ tNODES;在$ N2(在$ N(因为我在$(qstat命令| grep的EF|切-f 1 -d'');做J = $(回声$ I | sed的'S /(\\ d +)\\ .. + / $ 1 /');参阅qstat -f | grep的-A43 $焦耳;完成| grep的Resource_List.nodes);做回声$ {N} ;完成| grep的PPN);做回声附加$ J $ {N2:0:1}; totalNodes = $(($ totalNodes + $ {N2:0:1}));完成;回声16 $ totalNodes节点EF队列运行


解决方案

命令替换法 $(),所以如果你的内部定义一个变量运行在一个子shell在它的命令它的变量的值会丢失之外。

  J = 1
:$(J = 2)
回声$ J#=> 1

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"
解决方案

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

这篇关于这BASH code工作在命令行上,而不是当我把它移动到一个脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 07:53