【问题标题】:Can IFS be changed locally in a Bash function?可以在 Bash 函数中本地更改 IFS 吗?
【发布时间】:2018-06-06 20:16:34
【问题描述】:

我有一个函数需要更改 IFS 的逻辑:

my_func() {
  oldIFS=$IFS; IFS=.; var="$1"; arr=($var); IFS=$oldIFS
  # more logic here
}

我是否可以在函数内将 IFS 声明为 local IFS,这样我就不必担心支持其当前值并在以后恢复?

【问题讨论】:

  • 为什么在调用你的函数时不改变IFS的值onlyIFS=. my_func "some arg"
  • 我不希望调用者承担这个责任,这样调用者和被调用者之间就没有耦合。

标签: bash shell local ifs


【解决方案1】:

是的,可以定义!

只要定义了local,函数中的值设置不会影响全局IFS的值。下面看看sn-ps的区别

addNumbers () {
    local IFS='+'
    printf "%s\n" "$(( $* ))"
}

在命令行中调用时,

addNumbers 1 2 3 4 5 100
115

做事

nos=(1 2 3 4 5 100)
echo "${nos[*]}"

从命令行。上述echo 输出上的hexdump 不会显示函数中定义的IFS

echo "${nos[*]}" | hexdump -c
0000000   1       2       3       4       5       1   0   0  \n
000000e

在我的一个答案中查看我如何使用本地化的 IFS 进行算术 - How can I add numbers in a bash script

【讨论】:

    【解决方案2】:

    它似乎可以按您的意愿工作。

    #!/bin/bash
    changeIFSlocal() {
        local IFS=.
        echo "During local: |$IFS|"
    }
    changeIFSglobal() {
        IFS=.
        echo "During global: |$IFS|"
    }
    echo "Before: |$IFS|"
    changeIFSlocal
    echo "After local: |$IFS|"
    changeIFSglobal
    echo "After global: |$IFS|"
    

    打印出来:

    Before: |
    |
    During local: |.|
    After local: |
    |
    During global: |.|
    After global: |.|
    

    【讨论】:

      【解决方案3】:

      我很困惑,因为我在函数内部将 IFS 的值更改为 :(不使用 local),然后在调用函数后尝试使用此命令显示 IFS 的值:

      echo $IFS
      

      它显示了一个空行,让我觉得该功能没有改变 IFS。发布问题后,我意识到分词在起作用,我应该使用

      echo "$IFS"
      

      printf '%s\n' "$IFS"
      

      或者,甚至更好

      set | grep -w IFS=
      

      准确显示IFS值。

      回到局部变量的主题,是的,任何变量都可以在函数内声明为local以限制范围,除了已声明为只读的变量(带有readonlydeclare -r内置命令)。这包括 Bash internal 变量,如 BASH_VERSINFO 等。

      来自help local

      本地:本地 [选项] 名称[=值] ...

      Define local variables.
      
      Create a local variable called NAME, and give it VALUE.  OPTION can
      be any option accepted by `declare'.
      
      Local variables can only be used within a function; they are visible
      only to the function where they are defined and its children.
      
      Exit Status:
      Returns success unless an invalid option is supplied, a variable
      assignment error occurs, or the shell is not executing a function.
      

      【讨论】:

        【解决方案4】:

        您可以将IFS 指定为local 变量;本地版本仍用作字段分隔符字符串。

        有时在完全隔离的环境中运行函数很有用,在这种环境中没有永久更改。 (例如,如果函数需要更改 shell 选项。)这可以通过使函数在子 shell 中运行来实现;只需将函数定义中的{} 更改为()

        f() ( 
          shopt -s nullglob
          IFS=.
          # Commands to run in local environment
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-04-10
          • 1970-01-01
          • 2017-12-14
          • 2022-07-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多