【问题标题】:Is there any way to convert a literal to a non literal variable in bash? [duplicate]有没有办法在bash中将文字转换为非文字变量? [复制]
【发布时间】:2022-01-21 14:38:14
【问题描述】:

我的目标是拥有一个包含每个值的特定命令的数组。然而,为了让 bash 处理数组,我需要创建由 '' 包围的文字值

当尝试通过数组处理时,文字值(包括变量语法)将作为其文字名称而不是其变量名称进行处理。无论如何将文字值转换为非文字值?

这是我的意思的一个例子:

#!/bin/bash
dir=C
echo "Non literal"
ls $dir
echo "Literal"
'ls $dir'
echo "variable with literal
cmd='ls $dir'
echo $cmd
echo "$cmd"

$ ./test.sh
Non literal
01_hello_world  Modern_C  PLE_LinkedIn_Learning_C  The_C_Programming_Language
Literal
./test.sh: line 6: ls $dir: command not found
variable with literal
ls $dir
ls $dir

从“文字声明”中,我希望能够将'ls $dir' 转换为"ls $dir",因此$dir 被处理为C

这可能吗?

编辑

我想包含我的实际脚本,该脚本将处理来自数组的命令列表(我最初的目标):

#!/bin/bash

dir=C
tree_cmd=tree

run_cmds(){
    if [[ -z "$@" ]]; then
        echo "Array is empty"
    else
        for i in "$@"; do
            $i
        done
    fi
}

arr=(
'ls $dir'
'cat $dir/01_hello_world'
'$tree_cmd $dir'
)

run_cmds "${arr[@]}"

【问题讨论】:

  • 您在寻找eval 'ls $dir' 吗?即使在这种情况下,您也应该引用dir 并使用eval 'ls "$dir"',但是......几乎可以肯定有更好的方法来解决您的实际问题。
  • 请注意,尽管eval "$cmd" 几乎可以肯定“解决”您的直接问题,但它会打开一大堆您可能不想担心的蠕虫。
  • shell 没有您声称的文字值和非文字值之间的那种区别。您的问题是关于引用及其对参数扩展的影响。这不是值的一部分,而是用于分配值的特定命令的属性。
  • My goal is to have an array that includes specific commands for each value 我们可以专注于目标吗? “每个值的特定命令”是什么意思?什么价值,什么价值?可以解释你想要什么,忽略所有“文字非文字”的东西吗?
  • @KamilCuk 我更新了我的帖子以包含我构建的测试数组脚本的上下文。注意我的数组有引用变量的命令,我想将它传递给一个函数,该函数将运行数组中的每个命令(值)。这有帮助吗?

标签: bash variables replace literals


【解决方案1】:

不要将命令存储在字符串中。使用函数。

引用变量扩展。

使用 shellcheck 检查您的脚本。

#!/bin/bash

dir=C
tree_cmd=tree

run_cmds(){
    if ((!$#)); then
        echo "No argumetns given"
    else
        local i
        for i in "$@"; do
            "$i"
        done
    fi
}

cmd_1() {
       ls "$dir"
}
cmd_2() {
       cat "$dir"/01_hello_world
}
cmd_3() {
      "$tree_cmd" "$dir"
}
arr=( cmd_1 cmd_2 cmd_3 )

run_cmds "${arr[@]}"

如果您真的想将命令存储在字符串中,例如出于简短测试目的而忽略一些最佳实践,请参阅https://mywiki.wooledge.org/BashFAQ/048。仍然引用变量扩展。你可以这样做:

#!/bin/bash

dir=C
tree_cmd=tree

run_cmds(){
    local  i
    for i in "$@"; do
        eval "$i"
    done
}

arr=(
  'ls "$dir"'
  'cat "$dir"/01_hello_world'
  '"$tree_cmd" "$dir"'
)

run_cmds "${arr[@]}"

【讨论】:

  • 绝对不想使用 eval,出于安全原因,我倾向于回避它。 Re: 函数方法,完美,谢谢!
猜你喜欢
  • 2017-12-21
  • 1970-01-01
  • 2020-09-12
  • 2019-08-30
  • 2017-10-10
  • 1970-01-01
  • 2011-02-23
  • 2020-12-23
  • 1970-01-01
相关资源
最近更新 更多