- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
据我所知,进程替换 <(...)/>(...) 创建了 fd
并将括号中的命令输出存储到生成的 fd 中。
因此,这两个命令是等价的
$ ls -al
$ cat <(ls -al)
If a process substitution is expanded as an argument to a function, expanded to an environment variable during calling of a function, or expanded to any assignment within a function, the process substitution will be "held open" for use by any command within the function or its callees, until the function in which it was set returns. If the same variable is set again within a callee, unless the new variable is local, the previous process substitution is closed and will be unavailable to the caller when the callee returns.
In essence, process substitutions expanded to variables within functions remain open until the function in which the process substitution occured returns - even when assigned to locals that were set by a function's caller. Dynamic scope doesn't protect them from closing.
#!/bin/bash
test_subs () {
echo "Inside a function"
FD2=<(ls -al)
cat $FD1
cat $FD2
}
FD1=<(ls -al)
test_subs
Result======================================
Inside a function
cat: /dev/fd/63: No such file or directory
cat: /dev/fd/63: No such file or directory
最佳答案
TL; 博士
似乎没有文档,因此无法保证进程替换的范围 <(...)
.我认为保持进程替换在范围内的唯一安全方法是将它们直接定义为参数 cmd <(...)
, 即时导出的变量 VAR=<(...) cmd
,或重定向 cmd < <(...)
.以这种方式定义的进程替换仍在范围内,而 cmd
在跑。
长篇大论
我像你一样解释了 Bash Hackers Wiki 中引用的文章。同样,我得出了同样的结论,即在函数内声明用于进程替换的变量并不能保证它们保持打开状态。在某些系统上,还有许多其他方法可以使它们保持打开状态,尤其是使用 command groups像子 shell (...)
和上下文 {...}
.但是,这些技巧在某些系统上仍然失败。
除了链接的 Bash Hackers Wiki 中的错误评论外,我找不到任何相关文档。偶bash's manual不谈进程替换的范围。所以我们坚持实验(或阅读 bash
的源代码,我没有)。
以下脚本创建了一些场景来检查何时进程替换 <(...)
仍在范围内。请注意,存在非常细微的差异。例如:使用 ;
在同一行中编写两个命令会有所不同。或每个命令在其自己的行中。当然,这份 list 并不完整。随意扩展它。
#! /usr/bin/env bash
echo 'define, use'
a=<(echo ok);
cat "$a"; unset a
echo 'define and use in same line'
a=<(echo ok); cat "$a"; unset a
echo 'define and use in subshell'
(a=<(echo ok);
cat "$a")
echo 'define and use in context'
{ a=<(echo ok)
cat "$a"; }; unset a
echo 'define and use in && chain'
a=<(echo ok) &&
cat "$a"; unset a
echo 'define in context and use in || chain'
{ a=<(echo ok); false; } || cat "$a"; unset a
echo 'define and use in for loop body'
for i in 1; do
a=<(echo ok)
cat "$a"
done
echo 'define and use in while loop head'
while
a=<(echo ok)
cat "$a"
false
do true; done; unset a
echo 'define and use in same case'
case x in
x)
a=<(echo ok)
cat "$a"
;;
esac; unset a
echo 'define in case, use in fall-through'
case x in
x)
a=<(echo ok)
;&
y)
cat "$a"
;;
esac; unset a
echo 'define and use inside function in same line'
f() { a=<(echo ok); cat "$a"; }; f; unset a f
echo 'define local and use inside function in same line'
f() { local a=<(echo ok); cat "$a"; }; f; unset a f
echo 'define, use as function argument'
f() { cat "$1"; }; a=<(echo ok)
f "$a"; unset a f
echo 'define, use as function argument in same line'
f() { cat "$1"; }; a=<(echo ok); f "$a"; unset a f
echo 'on-the-fly export, use in different shell'
a=<(echo ok) dash -c 'cat "$a"'
echo 'export, use in different shell'
export a=<(echo ok)
dash -c 'cat "$a"'; unset a
echo 'define in command substitution, use in parent in same line'
a=$(echo <(echo ok)); cat "$a"; unset a
echo 'read from here-string, use in parent in same line'
read a <<< <(echo ok); cat "$a"; unset a
echo 'read from process substitution, use in parent in same line'
read a < <(echo <(echo ok)); cat $a; unset a
echo 'read from pipe and use in same line'
shopt -s lastpipe; # TODO add `set +m` when running interactively
echo <(echo ok) | read -r a; cat "$a"
shopt -u lastpipe; unset a
echo 'define, unrelated read from file, use in same line'
a=<(echo ok); read < /etc/passwd; cat "$a"; unset a
echo 'define, unrelated read from process substitution, use in same line'
a=<(echo ok); read < <(echo unused); cat "$a"; unset a
echo 'define, unrelated cat from process substitution, use in same line'
a=<(echo ok); cat <(echo unused) > /dev/null; cat "$a"; unset a
echo 'define, unrelated read ... in subshell, use in same line'
a=<(echo ok); (read < <(echo unused)); cat "$a"; unset a b
echo 'define, unrelated read ... in command substitution, use in same line'
a=<(echo ok); b=$(read < <(echo unused)); cat "$a"; unset a b
# output can be prettified using
# ./script 2> /dev/null |
# awk 'p!="ok"{if($0=="ok")print "yes " p;else print "no " p}{p=$0}'
In scope on bash 5.0.17 on Arch Linux (kernel 5.6.15-arch1-1)
| In scope on bash 5.0.3 on Debian 10 Buster inside WSL 1
| | In scope on bash 4.3.48 on Ubuntu 16.04.6 LTS
↓ ↓ ↓
no no no define, use
yes yes no define and use in same line
yes yes no define and use in subshell
yes yes no define and use in context
yes yes no define and use in && chain
yes yes no define in context and use in || chain
yes yes no define and use in for loop body
yes yes no define and use in while loop head
yes yes no define and use in same case
yes yes no define in case, use in fall-through
no no no define and use inside function in same line
no no no define local and use inside function in same line
no no no define, use as function argument
yes yes no define, use as function argument in same line
yes yes yes on-the-fly export, use in different shell
no no no export, use in different shell
no no no define in command substitution, use in parent in same line
no no no read from here-string, use in parent in same line
no no no read from process substitution, use in parent in same line
no no no read from pipe and use in same line
yes yes no define, unrelated read from file, use in same line
yes no no define, unrelated read from process substitution, use in same line
yes yes no define, unrelated cat from process substitution, use in same line
no no no define, unrelated read ... in subshell, use in same line
yes yes no define, unrelated read ... in command substitution, use in same line
关于Bash:进程替换的范围是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46660020/
我用 IntelliJ IDEA 2021.1 CE 在 流行!_OS 20.04 与 bash 5.0.17 . 问题造句:我将IntelliJ终端设置为/bin/bash通过 IntelliJ 设
给定如下命令: bash --shortcuts 我想显示一个快捷方式列表,就像在这个页面上一样: http://www.skorks.com/2009/09/bash-shortcuts-for-m
我有一个脚本可以操作数据、创建参数并将它们发送到第二个脚本。其中一个参数包含一个空格。 脚本1.sh: args=() args+=("A") args+=("1 2") args+=("B") .
我的脚本的“只运行一次”版本的一个非常简单的示例: ./myscript.sh var1 "var2 with spaces" var3 #!/bin/bash echo $1 #output: va
我想了解数字( double )在 bash 中是如何表示的,以及当我在 bash 中以十六进制格式打印数字时会发生什么。 根据 IEEE 754 标准,double 应由 64 位表示:52 位(1
我试图在 bash -c "..." 命令中获取 bash 脚本,但它不起作用。 如果我在 bash -c "..." 之外运行命令,它会起作用。 我需要使用 bash -c "..." 因为我想确保
如何检测我的 bash shell 中是否加载了 bash 补全包?从 bash-completion 的 2.1 版(包含在 Debian 8 中)开始,除了 BASH_COMPLETION_COM
我的 bash_profile 中有一个投影函数。现在我试图从 bash 脚本中调用这个函数,但是我得到了一个未找到的错误。如何使投影函数对 bash 脚本可见? 最佳答案 必须导出函数 export
我正在编写一个 bash 脚本,它接受许多命令行参数(可能包括空格)并通过登录 shell 将它们全部传递给程序 (/bin/some_program)。从 bash 脚本调用的登录 shell 将取
当我创建一个新的 bash 进程时,提示符默认为一个非常简单的提示符。我知道我可以编辑 .bashrc 等来更改它,但是有没有办法使用 bash 命令传递提示? 谢谢! 最佳答案 提示由 PS1、PS
好的,我希望这个问题有一定道理,但是 bash shell 和 bash 终端之间有什么区别?例子。当我第一次打开终端时,会提示我当前的目录和用户名。在终端窗口标题中显示 -bash- ,当我键入 e
我是 SBCL 的新手,我正在尝试从 bash 终端运行存储在文本文件中的 Lisp 脚本。 这是我在文件开头写的内容 http://www.sbcl.org/manual/#Running-from
我知道我们可以在 bash 中使用将十六进制转换为十进制 #!/bin/bash echo "Type a hex number" read hexNum echo $(( 16#$hexNum ))
我正在尝试在 bash 脚本中自动完成文件夹名称。如果我输入完整的文件夹名称,一切正常,但我不知道如何自动完成名称。有什么想法吗? repo() { cd ~/Desktop/_REPOS/$1 }
我想检查远程网站上的一些文件。 这里是bash命令生成计算文件md5的命令 [root]# head -n 3 zrcpathAll | awk '{print $3}' | xargs -I {}
是否有任何内置函数可以使用 bash shell 脚本从给定日期获取下周日(下周一、下周二等)?例如,2014 年 9 月 1 日之后的第一个星期日是什么时候?我预计 2014 年 9 月 7 日。
我一直在尝试根据表格重命名一些特定文件,但没有成功。它要么重命名所有文件,要么给出错误。 该目录包含数百个以长条形码命名的文件,我只想重命名包含模式 _1_ 的文件。 例子 barcode_1_bar
bash 中有没有办法用变量的内容替换文本文件中的占位符? 例如,我想发送一封电子邮件通知,如下所示: Dear Foo, Alert: blah blah blah blah blah blah
我有一个 bash 脚本,它在某些字符串上附加了一个重音字符,导致它失败,我找不到这些字符在哪里或如何进入那里。 这是一些示例输出: mv: cannot move â/tmp/myapp.zipâ
这个问题在这里已经有了答案: How do I place stdout on edit line? (1 个回答) Can a bash script prepopulate the prompt
我是一名优秀的程序员,十分优秀!