标签: command-substitution

如何避免bash命令替换删除换行符?

为了加速一些bash脚本执行,我想使用命令替换将命令的结果保存在变量中,但是命令替换用0x0A空格替换换行符.例如:

a=`df -H`
Run Code Online (Sandbox Code Playgroud)

要么

a=$( df -H )
Run Code Online (Sandbox Code Playgroud)

当我想进一步处理时$a,换行符被空格替换,所有行现在都在一行上,这更难以grep:

echo $a
Run Code Online (Sandbox Code Playgroud)

什么是避免命令替换删除换行符的简单技巧?

bash newline command-substitution

70
推荐指数
1
解决办法
2万
查看次数

如何将命令的输出分配到数组中?

我需要将结果从a分配grep给一个数组......例如

grep -n "search term" file.txt | sed 's/:.*//'
Run Code Online (Sandbox Code Playgroud)

这导致了一系列行号,其中找到了搜索词.

1
3
12
19
Run Code Online (Sandbox Code Playgroud)

将它们分配给bash数组的最简单方法是什么?如果我只是将它们分配给变量,它们就会变成一个以空格分隔的字符串.

arrays bash command-substitution

63
推荐指数
3
解决办法
8万
查看次数

Backticks vs Bash中的大括号

当我去回答这个问题时,我打算使用这个${}符号,因为我在这里已经看过很多次,所以最好用反引号.

但是,当我尝试

joulesFinal=${echo $joules2 \* $cpu | bc}
Run Code Online (Sandbox Code Playgroud)

我收到了消息

-bash: ${echo $joules * $cpu | bc}: bad substitution
Run Code Online (Sandbox Code Playgroud)

joulesFinal=`echo $joules2 \* $cpu | bc`
Run Code Online (Sandbox Code Playgroud)

工作良好.那么我需要做出哪些其他改变呢?

bash command-substitution

45
推荐指数
2
解决办法
3万
查看次数

鱼相当于bash $(命令)表示法

我目前正在试用鱼壳而不是使用bash.我在学习鱼类等效符号方面遇到困难的一种符号$(command)类似于此SOF帖子中的描述.我怎么用鱼写这个?请记住,我可以在我想要评估的命令周围使用反斜杠字符,但链接的帖子和其他帖子不鼓励这样做,因为它是评估命令的旧样式.

具体来说,这是我要转换为fish语法的bash命令(用于在shell启动期间初始化rbenv):

eval "$(rbenv init -)"
Run Code Online (Sandbox Code Playgroud)

shell fish command-substitution

29
推荐指数
3
解决办法
9089
查看次数

退出bash局部变量赋值中的命令替换代码

如果赋值是函数中的局部变量,如何在bash中检查命令替换的退出代码?
请参阅以下示例.第二个是我想检查退出代码的地方.
有人有一个良好的解决方案或正确的解决方案吗?

$ function testing { test="$(return 1)"; echo $?; }; testing
1
$ function testing { local test="$(return 1)"; echo $?; }; testing
0
Run Code Online (Sandbox Code Playgroud)

bash local-variables exit-code command-substitution

26
推荐指数
1
解决办法
4506
查看次数

什么时候命令替换会产生比单独的相同命令更多的子shell?

昨天有人向我建议在bash中使用命令替换会导致产生不必要的子shell.该建议仅针对此用例:

# Extra subshell spawned
foo=$(command; echo $?)

# No extra subshell
command
foo=$?
Run Code Online (Sandbox Code Playgroud)

我认为这对于这个用例似乎是正确的.但是,快速搜索试图验证这会导致大量令人困惑和矛盾的建议.似乎流行的智慧说所有命令替换的使用都会产生一个子shell.例如:

命令替换扩展为命令的输出.这些命令在子shell中执行,其stdout数据是替换语法扩展的内容.(来源)

这看起来很简单,除非你继续挖掘,在这种情况下你会开始找到建议的参考,但事实并非如此.

命令替换不一定会调用子shell,在大多数情况下也不会.它唯一保证的是乱序评估:它只是首先评估替换中的表达式,然后使用替换结果评估周围的语句.(来源)

这似乎是合理的,但这是真的吗?这个与子shell相关的问题的回答让我觉得有点man bash需要注意:

管道中的每个命令都作为单独的进程执行(即,在子shell中).

这让我想到了主要问题.究竟是什么导致命令替换产生一个副本,这个子shell无论如何都不会被隔离地执行相同的命令?

请考虑以下情况并解释哪些情况会产生额外子shell的开销:

# Case #1
command1
var=$(command1)

# Case #2
command1 | command2
var=$(command1 | command2)

# Case #3
command1 | command 2 ; var=$?
var=$(command1 | command2 ; echo $?)
Run Code Online (Sandbox Code Playgroud)

这些对中的每一对都会产生相同数量的子壳来执行吗?POSIX与bash实现有区别吗?是否有其他情况下使用命令替换会产生一个子shell,在这种情况下运行同一组命令不会?

bash shell optimization subshell command-substitution

24
推荐指数
2
解决办法
2596
查看次数

命令替换与进程替换

我试图理解这两个相似命令之间的差异.

aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
Run Code Online (Sandbox Code Playgroud)
  • 我知道这<()需要#!/bin/bash,但这会让它变慢吗?
  • 他们创造了相同数量的子壳吗?
  • 他们是否需要相同数量bashsh流程?

我希望使用具有最佳性能的命令.

bash process-substitution command-substitution

15
推荐指数
1
解决办法
3137
查看次数

在msys bash上包含换行符时,PS1命令替换失败

此命令成功

$ PS1='$(date +%s) $ '
1391380852 $

但是,如果我添加换行符,则会失败

$ PS1='$(date +%s)\n$ '
bash: command substitution: line 1: syntax error near unexpected token `)'
bash: command substitution: line 1: `date +%s)'

如果我使用反引号就行了

$ PS1='`date +%s`\n$ '
1391381008
$

但是反叛是沮丧的.那是什么导致了这个错误?

GNU bash, version 4.2.45(6)-release

bash backticks ps1 command-substitution

14
推荐指数
1
解决办法
2711
查看次数

如何在 Dockerfile 中使用命令替换

在我的 Dockerfile 中,我需要使用命令替换来添加一些环境变量。我想设置

ENV PYTHONPATH /usr/local/$(python3 -c 'from distutils import sysconfig; print(sysconfig.get_python_lib())')
Run Code Online (Sandbox Code Playgroud)

但它不起作用。结果是

foo@bar:~$ echo $PYTHONPATH
/usr/local/$(python3 -c from distutils import sysconfig; print(sysconfig.get_python_lib()))
Run Code Online (Sandbox Code Playgroud)

怎么了?

command-substitution dockerfile

9
推荐指数
1
解决办法
6509
查看次数

这个shell语法的机制:$ {1: - $(</ dev/stdin)}

我最近遇到了这个非常简洁的语法,在创建bash可以接受来自STDIN的参数或流的函数的上下文中(即可以通过管道传递).从表面上看,我理解这里发生了什么,但我想更多地解释一下这是如何工作的实际机制.

这是语法(根据标题): ${1:-$(</dev/stdin)}

在上下文中,可以将其用作:

log(){
 echo -e >&1 "INFO: ${1:-$(</dev/stdin)}"
}
Run Code Online (Sandbox Code Playgroud)

允许以下用法:

$ log foo
INFO: foo
Run Code Online (Sandbox Code Playgroud)

或者,您也可以这样做

mv -v foo.ext bar.ext | log
INFO: renamed 'foo.ext' -> 'bar.ext'
Run Code Online (Sandbox Code Playgroud)

这很棒,因为它是我看到的用于启用参数和管道功能的单一最简洁的方法bash(不幸的是我忘记了我现在遇到它的地方).

现在,我理解(或者我认为我理解),这里发生的大部分事情至少表面上看,但我会更加理解.这是我如何解释它,然后是我剩下的问题:

${1:-$(</dev/stdin)}

  • ${1} 显然是函数接受的默认参数
  • ${1:-x}是否为变量/大括号扩展'后退'到字符串'x',$1否则为空(或未设置?).在这种情况下,回退到STDIN进程子.
  • $()显然是一个进程命令替换
  • 最后,</dev/stdin显然是标准输入的重定向,它允许管道工作.

这基本上说如果$1不是由参数填充,则回退到使用STDIN - 我在概念上很满意.

所以这是我的问题:

  1. 我从来没有<进程命令替换中看到redirect(),没有在它之前的实际命令(例如$(cat < somefile.ext)).那么当进程命令替换收到重定向而没有其他命令要调用时,实际发生了什么(细节)?
  2. 为什么有必要在进程命令替换中包装STDIN重定向?(实际上,当我写这个时,它发生在我身上,我没有测试它,但我会保持简单).
  3. 这样安全吗?我已经将它与多线STDIN一起使用了,到目前为止还没有破坏.这可能会降到哪里(如果在哪里?).

bash stdin command-substitution parameter-expansion

9
推荐指数
1
解决办法
210
查看次数