为了加速一些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)
什么是避免命令替换删除换行符的简单技巧?
我需要将结果从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数组的最简单方法是什么?如果我只是将它们分配给变量,它们就会变成一个以空格分隔的字符串.
当我去回答这个问题时,我打算使用这个${}符号,因为我在这里已经看过很多次,所以最好用反引号.
但是,当我尝试
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)类似于此SOF帖子中的描述.我怎么用鱼写这个?请记住,我可以在我想要评估的命令周围使用反斜杠字符,但链接的帖子和其他帖子不鼓励这样做,因为它是评估命令的旧样式.
具体来说,这是我要转换为fish语法的bash命令(用于在shell启动期间初始化rbenv):
eval "$(rbenv init -)"
Run Code Online (Sandbox Code Playgroud) 如果赋值是函数中的局部变量,如何在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中使用命令替换会导致产生不必要的子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,在这种情况下运行同一组命令不会?
我试图理解这两个相似命令之间的差异.
aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
Run Code Online (Sandbox Code Playgroud)
<()需要#!/bin/bash,但这会让它变慢吗?bash或sh流程?我希望使用具有最佳性能的命令.
此命令成功
$ 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
在我的 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)
怎么了?
我最近遇到了这个非常简洁的语法,在创建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 - 我在概念上很满意.
所以这是我的问题:
<在$(cat < somefile.ext)).那么当