Bash 子壳进位

Bash 子壳进位,bash,io-redirection,subshell,Bash,Io Redirection,Subshell,昨天我使用了flock,一些简单的概念变得清晰起来 我现在的问题是关于子壳。看看这个街区 ( flock -s 200 # ... commands executed under lock ... ) 200>/var/lock/mylockfile 我的理解是200>/var/lock/mylockfile在flock-s200之前运行,但是如果我尝试这样的方法 ( echo This is a sub-shell ) command 我从BASH得到一个错误 -bash:

昨天我使用了
flock
,一些简单的概念变得清晰起来

我现在的问题是关于子壳。看看这个街区

(
 flock -s 200 
 # ... commands executed under lock ... 
) 200>/var/lock/mylockfile
我的理解是
200>/var/lock/mylockfile
flock-s200
之前运行,但是如果我尝试这样的方法

( echo This is a sub-shell ) command
我从BASH得到一个错误

-bash: syntax error near unexpected token `command'
引入分号

( echo This is a sub-shell ); command
修复错误,但会导致在子shell返回后运行
命令

所以我想知道最初的示例是如何首先运行重定向的。这是否与
优先于子shell
(列表)
符号有关?我在BASH主页上找到了

运算符按优先级顺序计算。中的子表达式 括号首先求值,可能会覆盖优先规则 上面


在此上下文中,
200>/var/lock/mylockfile
是关于如何配置子shell(如何设置其重定向)的信息。这不是一个单独的命令

这与

echo "foo" >bar.txt
…始终首先执行重定向,就像

>bar.txt echo "foo"
在这两种情况下,顺序都不重要


子shell在这方面与之类似——它只是一个复合命令,与任何其他命令一样,它可以在其开始或结束时指定重定向。

200>/var/lock/mylock仅创建
mylock
,但仅此而已。 比如说,

$ 200>/var/lock/mylock;
$ echo "hello" >&200
bash: 200: bad file descriptor.
不起作用。如果要运行此操作,请添加exec:

$ exec 200>/var/lock/mylock;
$ echo "hello" >&200
$ cat /var/lock/mylock
hello
关于子shell:在编写时

(
   ...
) 200>/var/lock/myfile
bash使用
fork()
创建子级,然后子级使用
dup2
将1重定向到200,然后解析并执行
(…)
中的代码

因此,如果您希望在子shell之前创建文件,则需要一个解决方案

exec 200> /var/lock/file
(
  ...
) >&200

仅供参考,子shell和列表在语法上是不同的——它们有不同的解析器规则,尽管它们使用相同的字符(因此在lexer看来是相同的)。感谢Charles,我认为我有一个基本的误解。我会继续学习。顺便说一下,新版本的bash(4.1+)会为您分配FDs,所以您不必硬编码数字。因此,您可以使用
{lock\u fd}>/path/to/lockfile
flock-s“$lock\u fd”
谢谢Edouard,这也非常有用。在查看昨天借用的代码时,我想知道如何使用
exec
进行重定向。我会仔细研究你的例子。很好。我想我需要通读高级Bash脚本指南。主页本身就留下了一些需要改进的地方。@quickshiftin,我强烈建议使用BashGuide:;我们经常需要帮助人们改掉ABS在freenode's#bash中教给他们的坏习惯。谢谢Charles,我也来看看。