将 bash 中的命令输出解析为变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15309818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:47:29  来源:igfitidea点击:

Parsing command output in bash to variables

bash

提问by Nick Andriopoulos

I have a number of bash scripts, each doing its own thing merrily. Do note that while I program in other languages, I only use Bash to automate things, and am not very good at it.

我有许多 bash 脚本,每个脚本都愉快地做着自己的事情。请注意,虽然我使用其他语言进行编程,但我只使用 Bash 来自动化操作,并且不太擅长。

I'm now trying to combine a number of them to create "meta" scripts, if you will, which use other scripts as steps. The problem is that I need to parse the output of each step to be able to pass a part of it as params to the next step.

我现在正在尝试组合其中的一些来创建“元”脚本,如果你愿意的话,它使用其他脚本作为步骤。问题是我需要解析每个步骤的输出才能将其中的一部分作为参数传递给下一步。

An example:

一个例子:

stepA.sh

stepA.sh

[...does stuff here...]
echo "Task complete successfuly"
echo "Files available at: $d1/"
echo "Logs available at: $d2/"

both the above are paths, such as /var/www/thisisatest and /var/log/thisisatest (note that files always start with /var/www and logs always start with /var/log ). I'm only interested in the files path.

以上都是路径,例如 /var/www/thisisatest 和 /var/log/thisisatest (注意文件总是以 /var/www 开头,日志总是以 /var/log 开头)。我只对文件路径感兴趣。

steB.sh

steB.sh

[...does stuff here...]
echo "Creation of $d1 complete."
echo "Access with username $usr and password $pass"

all variables here are simple strings, that may contain special characters (no spaces)

这里的所有变量都是简单的字符串,可能包含特殊字符(无空格)

What I'm trying to build is a script that runs stepA.sh, then stepB.shand uses the output of each to do its own stuff. What I'm currently doing (both above scripts are symlinked to /usr/local/bin without the .shpart and made executable):

我正在尝试构建一个脚本,该脚本运行stepA.sh,然后stepB.sh使用每个脚本的输出来做自己的事情。我目前在做什么(以上两个脚本都符号链接到 /usr/local/bin 没有该.sh部分并使其可执行):

 #!/bin/bash

 stepA  | while read -r line; do
 # Create the container, and grab the file location
 # then pass it to then next pipe
   if [[ "$line" == *:* ]]
   then
     POS=`expr index "$line" "/"`
     PTH="/${line:$POS}"
     if [[ "$PTH" == *www* ]]
     then
       #OK, have what I need here, now what?
       echo $PTH;
     fi
   fi
done 

# Somehow get $PTH here

stepB  | while read -r line; do
 ...
done

#somehow have the required strings here

I'm stuck in passing the PTHto the next step. I understand this is because piping runs it in a subshell, however all examples I've seen refer to to files and not commands, and I could not make this to work. I tried piping the echoto a "next step" such as

我被困在传递PTH到下一步。我理解这是因为管道在子外壳中运行它,但是我看到的所有示例都指的是文件而不是命令,我无法使其工作。我尝试通过管道echo进行“下一步”,例如

stepA | while ...
    echo $PTH
done | while ...
 #Got my var here, but cannot run stuff
done

How can I run stepAand have the PTHvariable available for later? Is there a "better way" to extract the path I need from the output than nested ifs ?

我如何运行stepA并让PTH变量稍后可用?与嵌套ifs相比,是否有“更好的方法”可以从输出中提取我需要的路径?

Thanks in advance!

提前致谢!

回答by Gordon Davisson

Since you're using bash explicitly (in the shebang line), you can use its process substitution feature instead of a pipe:

由于您显式使用 bash(在 shebang 行中),您可以使用其进程替换功能而不是管道:

while read -r line; do
    if [[ "$line" == *:* ]]
        .....
    fi
done < <(stepA )

Alternately, you could capture the command's output to a string variable, and then parse that:

或者,您可以将命令的输出捕获到字符串变量中,然后对其进行解析:

output="$(stepA )"
tmp="${output#*$'\nFiles available at: '}" # output with everything before the filepath trimmed
filepath="${tmp%%$'\n'*}" # trim the first newline and everything after it from $tmp
tmp="${output#*$'\nLogs available at: '}"
logpath="${tmp%%$'\n'*}"