【问题标题】:Storing part of a command string as a variable in bash将命令字符串的一部分存储为 bash 中的变量
【发布时间】:2020-09-20 16:08:04
【问题描述】:

我正在使用一个变量来组合命令:

    #!/bin/bash
    cmd=$(sudo -i -u $domain wp --path=$path)
    $cmd post create --post_type=page --post_status=publish --post_title='Page1'
    $cmd post create --post_type=page --post_status=publish --post_title='Page110'
    $cmd widget delete $($cmd widget list sidebar-1 --format=ids)

edit1:使用 cmd='sudo -i -u $domain wp --path=$path';echo $cmd |bash

的示例
    #!/bin/bash
    cmd='sudo -i -u $domain wp --path=$path'
    echo $cmd --post_type=page --post_status=publish --post_title='Page1'|bash

    echo $cmd widget delete $(echo $cmd widget list sidebar-1 --format=ids|bash)|bash

尝试执行上述操作时出现错误。我试过用'single quotes'"double quotes" 代替(parenthesis),但是不行。

我知道我可以在完成时放入一个临时变量并替换,但我真的很想知道如何在 bash 中组合命令。

edit2:创建了一个简单版本来测试建议的答案:

#!/bin/bash
tmpcmd="history| grep "
echo "$tmpcmd ls"|bash

输出为:空白

【问题讨论】:

  • cmd=$(command) 将变量 cmd 设置为执行命令的输出。
  • 如上和......你可能想要cmd="sudo -i -u $domain wp --path=$path",但你上面包含的结构已经成熟,难以破译问题。祝你好运。
  • 请添加一个shebang,然后将您的脚本粘贴到shellcheck.net 并尝试实施那里提出的建议。
  • 在变量中存储命令(或其中的一部分)往往效果不佳,除非是简单的情况,最好避免。变量用于存储数据,而不是可执行代码。见BashFAQ #50: "I'm trying to put a command in a variable, but the complex cases always fail!"

标签: bash command string-interpolation


【解决方案1】:

您需要将所有命令存储为字符串,省略 '$(...)',运行命令 ... 并返回其 STDOUT(不是您想要的)。
然后使用echo "$cmd1 $cmd2 ..." | bash 在shell 中执行生成的命令。所有命令的双引号很重要,以防止将某些字符串视为echo 的选项:

cmd1='command 1 string'
cmd2='command 2 string'

# Execute: command 1 string command 2 string
echo "$cmd1 $cmd2" | bash

示例 1:

cmd1='sudo'
cmd2='purge'

# Runs: sudo purge
echo "$cmd1 $cmd2" | bash

示例 2:

脚本:

#!/usr/bin/env bash

tmpcmd="( echo 'foo' ; echo 'bar' ) | grep"
echo "with variable interpolation:"
echo "$tmpcmd 'foo'" | bash
echo "without variable interpolation:"
echo "( echo 'foo' ; echo 'bar' ) | grep 'foo'" | bash
echo "original command:"
( echo 'foo' ; echo 'bar' ) | grep 'foo'
echo 'done'

无论命令是否被插值以及是否按原样执行,输出都是相同的:

with variable interpolation:
foo
without variable interpolation:
foo
original command:
foo
done

示例 4(基于 OP 的示例,确认它没有按预期工作):

#!/usr/bin/env bash
ls > /dev/null
tmpcmd="history | grep"
echo "with variable interpolation:"
echo "$tmpcmd ls" | bash
echo "without variable interpolation:"
echo "history | grep ls" | bash
echo "original command:"
history | grep ls
echo 'done'

输出:

with variable interpolation:
without variable interpolation:
original command:
done

示例 4 不打印来自 history 命令的任何输出因为 bash 默认禁用非交互式 shell 中的历史记录。最好不要在此类 shell 脚本示例中使用 history。另见:
https://unix.stackexchange.com/q/5684/13411
https://unix.stackexchange.com/q/112354/13411

【讨论】:

  • hmmm,所以当有多个唯一的出现时,这可能不是理想的。如果我可以得到一个变量来运行 bash
  • 修正错别字,抱歉。
  • @stackmacstacky 你能澄清一下吗?一个具体的例子会有所帮助。最好是编辑问题 - 这样每个人都可以在同一页面上。
  • 添加了当我执行建议时会发生什么。返回空白
  • 我建议不要使用这种方法,因为它会导致引用和转义错误的各种方式(非常类似于 eval 可能出错的方式)。
猜你喜欢
  • 2023-01-12
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
  • 2022-06-15
  • 1970-01-01
相关资源
最近更新 更多