【问题标题】:Sub-shell precendence子外壳优先级
【发布时间】:2014-02-11 17:40:27
【问题描述】:

昨天我在got some clarification 周围使用flock 并且一些简单的概念对我来说变得清晰了。

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

(
 flock -s 200 
 # ... commands executed under lock ... 
) 200>/var/lock/mylockfile

我的理解是 200>/var/lock/mylockfile 运行 之前 flock -s 200,但是如果我尝试这样的事情

( echo This is a sub-shell ) command

我从 BASH 收到一个错误

-bash: syntax error near unexpected token `command'

引入分号

( echo This is a sub-shell ); command

修复了错误,但导致command 在子shell 返回后运行。

所以我想知道最初的示例如何导致重定向首先运行。这与> 优先于子外壳(list) 表示法有关吗?查看我发现的 BASH 手册页

运算符按优先顺序进行评估。中的子表达式 括号首先被评估并且可以覆盖优先规则 以上。

【问题讨论】:

  • 仅供参考,子shell 和列表在语法上是不同的——尽管使用相同的字符(因此在词法分析器中看起来相同),但它们具有不同的解析器规则。

标签: bash io-redirection subshell


【解决方案1】:

200>/var/lock/mylockfile 在这种情况下,是关于如何子shell应该配置的信息(应该如何设置它的重定向)。这不是一个单独的命令。

这与

echo "foo" >bar.txt

...总是首先进行重定向,就像

>bar.txt echo "foo"

在这两种情况下,顺序都不重要。

子shell在这方面是相似的——它只是一个复合命令,和任何其他命令一样,它可以在其开头或结尾指定重定向。

【讨论】:

  • 感谢这个查尔斯,我想我有一个根本的误解。我会继续学习的。
  • 顺便说一下,新版本的 bash (4.1+) 将为您分配 FD,因此您不必对数字进行硬编码。因此,您可以使用{lock_fd}>/path/to/lockfileflock -s "$lock_fd"
【解决方案2】:

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

现在关于子壳:写作时

(
   ...
) 200>/var/lock/myfile

bash 使用fork() 创建一个child,然后child 使用dup2 将1 重定向到200,然后解析并执行( ... ) 中的代码。

因此如果你想在子shell之前创建文件,一个解决方案是

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

【讨论】:

  • 谢谢 Edouard,这也非常很有帮助。在查看我从昨天借来的代码时,我想知道使用exec 进行重定向。我会在这里仔细研究你的例子。
  • 不错。我想我只需要通读 Advanced Bash-Scripting Guide。仅手册页就有一些不足之处。
  • @quickshiftin,我强烈建议使用 BashGuide:mywiki.wooledge.org/BashGuide;我们经常不得不帮助人们改掉 ABS 在 freenode 的#bash 中教给他们的坏习惯。
  • 谢谢查尔斯,我也看看这个。
猜你喜欢
  • 1970-01-01
  • 2011-04-20
  • 2019-08-15
  • 1970-01-01
  • 2018-11-28
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
相关资源
最近更新 更多