简体   繁体   English

Bash:获取命令输出以及命令内部的变量

[英]Bash: Get command output with variables inside the command

i have a bash/shell script and want to store a command output in a variable ( EXCLUDE_PATTERN ) and the command itself contains also variables ( FOLDERS and BUPATH ). 我有一个bash / shell脚本,想将命令输出存储在变量( EXCLUDE_PATTERN )中,并且命令本身也包含变量( FOLDERSBUPATH )。

the goal with this command is to replace the spaces in the variable FOLDERS with " --exclude="$BUPATH for use in an tar command 此命令的目标是用“ --exclude =” $ BUPATH“替换变量FOLDERS中的空格,以在tar命令中使用

if have defined the following variables in the script: 如果在脚本中定义了以下变量:

FOLDERS='folder1 folder2 folder3'
BUPATH='/opt/mypath'
CONFIG_BACKUP="/storage/backup.tar.gz"

FOLDER is a variable with a list of excluded folders FOLDER是具有排除文件夹列表的变量

BUPATH is a variable with a path BUPATH是具有路径的变量

Now i want to define a variable EXCLUDE_PATTERN with the pattern for a following tar command (tried 2 variations): 现在,我想为以下tar命令的模式定义变量EXCLUDE_PATTERN (尝试2种变化):

EXCLUDE_PATTERN=`echo $FOLDERS | sed 's/\ /" --exclude="$BUPATH\//g'`
EXCLUDE_PATTERN=`echo $FOLDERS | sed 's/\ /" --exclude="${BUPATH}\//g'`

Then the script runs the tar command: 然后脚本运行tar命令:

tar -C \"$BUPATH\" --exclude=\"$BUPATH/$EXCLUDE_PATTERN\" -czf \"$CONFIG_BACKUP\" .

It seems that the variable EXCLUDE_PATTERN is not recognizing the BUPATH variable: 似乎变量EXCLUDE_PATTERN无法识别BUPATH变量:

tar -C "/opt/mypath" --exclude="/opt/mypath/folder1" --exclude="${BUPATH}/folder2" --exclude="${BUPATH}/folder3" -czf "/storage/config.tar.gz" .

The expected command should be this: 预期的命令应为:

tar -C "/opt/mypath" --exclude="/opt/mypath/folder1" --exclude="/opt/mypath/folder2" --exclude="/opt/mypath/folder3" -czf "/storage/config.tar.gz" .

I hope someone can help me with this :) 我希望有人可以帮助我:)

FOLDERS='folder1 folder2 folder3' FOLDERS ='folder1 folder2 folder3'

BUPATH='/opt/mypath' BUPATH ='/ opt / mypath'

CONFIG_BACKUP="/storage/backup.tar.gz" CONFIG_BACKUP =“ / storage / backup.tar.gz”

The expected command should be this: 预期的命令应为:

tar -C "/opt/mypath" --exclude="/opt/mypath/folder1" --exclude="/opt/mypath/folder2" --exclude="/opt/mypath/folder3" -czf "/storage/config.tar.gz" . tar -C“ / opt / mypath” --exclude =“ / opt / mypath / folder1” --exclude =“ / opt / mypath / folder2” --exclude =“ / opt / mypath / folder3” -czf“ / storage /config.tar.gz”。

Well, that's simple. 好吧,这很简单。 I like the xargs printf to transform a list, ex. 我喜欢xargs printf来转换列表,例如。 prepend something: 前置:

# creates a bash array from newline separated output
IFS=$'\n' tarexcludes=($(<<<"$FOLDERS" xargs -n1 printf "--exclude=%s/%s\n" "$BUPATH"))
echo tar -C "/opt/mypath" "${tarexcludes[@]}" -czf "$CONFIG_BACKUP" .

But alternatively you could pick a unique sed command separator and: 但是,您也可以选择一个独特的sed命令分隔符,然后执行以下操作:

tarexcludes=($(<<<"$FOLDERS" tr ' ' '\n' | sed "s~^~--exclude=$BUPATH/~"))

Or use awk : 或使用awk

tarexcludes=($(<<<"$FOLDERS" tr ' ' '\n' | awk -v BUPATH="$BUPATH" '{print "--exclude=" BUPATH "/" $0}')

Notes: 笔记:

  • Don't use backticks `. 不要使用反引号`。 They are discouraged and I don't like them. 他们灰心丧气,我不喜欢他们。 bash obsolete and deprecated syntax bash过时和不赞成使用的语法
  • The <<<"$FOLDERS" is bash's here string <<<"$FOLDERS"是bash的此处字符串
  • The tr ' ' '\\n' substitutes spaces for newline. tr ' ' '\\n'用空格代替换行符。 So it is parsable with sed. 因此它可以用sed解析。
  • The tarexcludes=( ... ) creates a bash array. tarexcludes=( ... )创建一个bash数组。 bashguide arrays bashguide数组
  • You command does not work because echo $FOLDERS will output on a single line, and sed parses lines. 您的命令不起作用,因为echo $FOLDERS将在单行上输出,并且sed解析行。 So just replace spaces with newlines. 因此,只需用换行符替换空格。 Alternatively, use xrandr -n1 or printf "%s" $FOLDERS 或者,使用xrandr -n1printf "%s" $FOLDERS
  • By convention, upper case variable names are by convention reserved to environmentally exported variables. 按照约定,大写变量名按照约定保留给环境导出的变量。 Use lowercase variable names in your scripts. 在脚本中使用小写的变量名。

You can also use a combination of " # instead of ' / as to solve your issue. 您也可以结合使用" #代替' /来解决您的问题。

EXCLUDE_PATTERN=`echo $FOLDERS |  sed -e "s#\ #\" --exclude=$BUPATH\"/#g"`

but this will output: 但这将输出:
folder1" --exclude=/opt/mypath"/folder2" --exclude=/opt/mypath"/folder3

To archive the expected output, it requires this modification: 要存档预期的输出,需要进行以下修改:

EXCLUDE_PATTERN=`echo $FOLDERS |  sed -e "s#\(\S\+\)# --exclude=\"$BUPATH/\1\"#g"`

this will output: 这将输出:
--exclude="/opt/mypath/folder1" --exclude="/opt/mypath/folder2" --exclude="/opt/mypath/folder3"

For more information read the StackOverflow post: 有关更多信息,请阅读StackOverflow文章:
Escape a string for a sed replace pattern 转义sed替换模式的字符串

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM