【问题标题】:Saving function output into a variable named in an argument将函数输出保存到参数中命名的变量中
【发布时间】:2017-05-17 22:30:03
【问题描述】:

我有一个有趣的问题,我似乎无法找到答案。我正在创建一个简单的应用程序,它将帮助我的开发部门使用 NginX 和配置文件自动启动 docker 容器。我的问题是,由于某种原因,在扫描目录时,我无法让 bash 脚本存储文件夹的名称。这是我所说的一个非常简单的例子......

#!/bin/bash

getFolder() {
    local __myResultFolder=$1
    local folder
    for d in */ ; do
        $folder=$d
    done
    __myResultFolder=$folder
    return $folder
}

getFolder FOLDER

echo "Using folder: $FOLDER"

然后我将这个简单的脚本保存为 folder_test.sh 并将其放在只有一个文件夹的文件夹中,将所有者更改为我,并为其授予正确的权限。但是,当我运行脚本时,我不断收到错误...

./folder_test.sh: 8 ./folder_test.sh: =test_folder/: not found

我尝试将$folder=$d 部分放在不同类型的引号中,但没有任何效果。我试过$folder="'"$d"'"$folder=`$d`$folder="$d",但都没有。让我发疯,任何帮助将不胜感激。谢谢。

【问题讨论】:

  • shellcheck.net 会自动为您捕获。
  • 顺便说一句,如果你不标记local d,你就会把它泄露到你的函数的外部范围中。
  • 人力资源部。不过,更仔细地阅读——您的目标是执行间接任务?抱歉——我不应该关闭它。

标签: bash nginx docker sh


【解决方案1】:

罪魁祸首是线

$folder=$d

将文件夹名称处理为之前使用= 符号存储并尝试以该名称扩展它,即字面上将名称=test_folder/ 视为要在shell 下运行的可执行文件,但找不到该文件姓名。改成

folder=$d

另外,bash 函数的返回值仅限于整数类型,您不能将字符串发送给调用函数。如果您想在 $folder 为空时向调用函数发送非零返回码,您可以添加一行

if [ -z "$folder" ]; then return 1; else return 0; fi

(或)如果你想从函数中返回一个字符串值,不要使用return,只需使用名称的echo并使用函数名称的命令替换,即

getFolder() {
    local __myResultFolder=$1
    local folder
    for d in */ ; do
        folder=$d
    done
    __myResultFolder=$folder
    echo "$folder"
}

folderName=$(getFolder FOLDER)
echo "$folderName"

【讨论】:

  • “只是不做间接赋值”方法有一些优点——尤其是在可移植性和简单性方面——但有时在性能、范围和变量持久性方面存在限制(考虑你在想要为临时查找维护缓存——任何缓存在子shell中的东西都会在函数退出时丢失)使其无法使用。
【解决方案2】:

如果你想将你的结果保存到一个命名变量中,你所做的就是所谓的“间接赋值”;它被 BashFAQ #6 覆盖。

一种方法如下:

#!/bin/bash
#      ^^^^ not /bin/sh; bash is needed for printf -v

getFolder() {
  local __myResultFolder=$1
  local folder d
  for d in */ ; do
    folder=$d
  done
  printf -v "$__myResultFolder" %s "$folder"
}

getFolder folderName
echo "$folderName"

其他方法包括:

  • 使用read

    IFS= read -r -d '' "$__myResultFolder" < <(printf '%s\0' "$folder")
    
  • 使用eval(非常非常小心):

    # note \$folder -- we're only trusting the destination variable name
    # ...not trusting the content.
    eval "$__myResultFolder=\$folder"
    
  • 使用namevars(仅在使用新版本的 bash 时):

    getFolder() {
      local -n __myResultFolder=$1
      # ...your other logic here...
      __myResultFolder=$folder
    }
    

【讨论】:

    猜你喜欢
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 2010-12-24
    • 2013-04-14
    • 1970-01-01
    • 2017-12-01
    相关资源
    最近更新 更多