可以在 Bash 函数中本地更改 IFS 吗?
Can IFS be changed locally in a Bash function?
我有一个函数需要更改 IFS 的逻辑:
my_func() {
oldIFS=$IFS; IFS=.; var=""; arr=($var); IFS=$oldIFS
# more logic here
}
我能否在函数内将 IFS 声明为 local IFS
,这样我就不必担心备份其当前值并稍后恢复?
可以定义!
只要定义local
,在函数中设置值不影响全局IFS
值。查看以下片段之间的区别
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
它似乎如您所愿。
#!/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: |.|
您可以将IFS
指定为local
变量;本地版本仍然用作字段分隔符字符串。
有时 运行 在完全隔离的环境中使用函数很有用,在这种环境中没有永久性的更改。 (例如,如果函数需要更改 shell 选项。)这可以通过在 subshell 中使函数 运行 来实现;只需将函数定义中的 {}
更改为 ()
:
f() (
shopt -s nullglob
IFS=.
# Commands to run in local environment
)
我很困惑,因为我在函数内部将 IFS 的值更改为 :
(未使用 local
),然后在调用函数后尝试使用此命令显示 IFS 的值:
echo $IFS
它显示了一个空行,让我觉得函数没有改变 IFS。发布问题后,我意识到分词在起作用,我应该使用
echo "$IFS"
或
printf '%s\n' "$IFS"
或者,甚至更好
set | grep -w IFS=
准确显示 IFS 值。
回到局部变量的主题,是的,任何变量都可以在函数内部声明为local
以限制范围,除了已经声明为只读的变量(使用readonly
或 declare -r
内置命令)。这包括 Bash internal 变量,例如 BASH_VERSINFO
等
来自help local
:
local: local [option] name[=value] ...
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.
我有一个函数需要更改 IFS 的逻辑:
my_func() {
oldIFS=$IFS; IFS=.; var=""; arr=($var); IFS=$oldIFS
# more logic here
}
我能否在函数内将 IFS 声明为 local IFS
,这样我就不必担心备份其当前值并稍后恢复?
可以定义!
只要定义local
,在函数中设置值不影响全局IFS
值。查看以下片段之间的区别
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
它似乎如您所愿。
#!/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: |.|
您可以将IFS
指定为local
变量;本地版本仍然用作字段分隔符字符串。
有时 运行 在完全隔离的环境中使用函数很有用,在这种环境中没有永久性的更改。 (例如,如果函数需要更改 shell 选项。)这可以通过在 subshell 中使函数 运行 来实现;只需将函数定义中的 {}
更改为 ()
:
f() (
shopt -s nullglob
IFS=.
# Commands to run in local environment
)
我很困惑,因为我在函数内部将 IFS 的值更改为 :
(未使用 local
),然后在调用函数后尝试使用此命令显示 IFS 的值:
echo $IFS
它显示了一个空行,让我觉得函数没有改变 IFS。发布问题后,我意识到分词在起作用,我应该使用
echo "$IFS"
或
printf '%s\n' "$IFS"
或者,甚至更好
set | grep -w IFS=
准确显示 IFS 值。
回到局部变量的主题,是的,任何变量都可以在函数内部声明为local
以限制范围,除了已经声明为只读的变量(使用readonly
或 declare -r
内置命令)。这包括 Bash internal 变量,例如 BASH_VERSINFO
等
来自help local
:
local: local [option] name[=value] ...
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.