我正在使用bash脚本,我想执行一个函数来打印返回值:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Run Code Online (Sandbox Code Playgroud)
当我执行时fun2
,它不会打印"34".为什么会这样?
我有这样的awk
声明:
glb_library="my_library"
awk "
/^Direct Dependers of/ { next }
/^---/ { next }
/^$glb_library:/ { ver=\$0; next }
{ gsub(/[[:space:]]/, '', \$0); print ver':'\$0 }
" file
Run Code Online (Sandbox Code Playgroud)
基本上,我已将awk
代码括在双引号中,以便glb_library
扩展shell变量.我已经确保逃避$
角色以防止外壳扩展$0
.遵循这里的指导.
awk
给我这个错误:
awk: syntax error at source line 5
context is
{ gsub(/[[:space:]]/, >>> ' <<<
Run Code Online (Sandbox Code Playgroud)
我想明白:
awk
?为什么''
不是像空字符串一样""
?awk
区别对待单引号和双引号?在我用反斜杠转义单引号并用来\"\"
表示空字符串而不是代码之后,我的代码工作''
.
我知道如果我print ("f" + 2 * "o")
在python中输出将是foo
.
但是如何在bash脚本中执行相同的操作呢?
我认为将IFS设置为$'\n'
可以帮助我将整个文件读入数组,如下所示:
IFS=$'\n' read -r -a array < file
Run Code Online (Sandbox Code Playgroud)
但是,以上命令仅将文件的第一行读入数组的第一元素,而没有其他内容。
即使这样,它也只读取数组的第一行:
string=$'one\ntwo\nthree'
IFS=$'\n' read -r -a array <<< "$string"
Run Code Online (Sandbox Code Playgroud)
我在该站点上碰到过其他文章,这些文章谈论使用mapfile -t
或read
循环将文件读入数组。
现在我的问题是:什么时候使用IFS=$'\n'
?
考虑以下简单的 bash 脚本:
#!/bin/bash
set -eou pipefail
IFS=$'\n\t'
gen() {
seq 0 3
}
for c in $(gen); do
echo c
done
echo "finish"
Run Code Online (Sandbox Code Playgroud)
它已经set -e
设置,所以当出现故障时,它应该以非零退出代码退出。
它将调用gen
函数并打印 的输出seq 0 3
,将打印finish
并以 code=0 退出。
如果我修改gen
失败,例如,通过调用seqqq
命令(不存在)来代替:
$ ./script.sh; echo $?
./script.sh: line 6: seqqq: command not found
finish
0
Run Code Online (Sandbox Code Playgroud)
set -e
它从子 shell 打印错误消息,它不会像预期的那样立即失败并立即退出(使用非零代码) ;它继续执行并以 code=0 退出。
这背后的解释是什么?请注意,如果我只是用我的 for 循环替换,它会按预期失败:
#!/bin/bash
set -eou pipefail
IFS=$'\n\t'
gen() {
seqqq 0 3
} …
Run Code Online (Sandbox Code Playgroud) 我试图用来eval
运行传递给函数的命令$@
.
这是我的代码:
run_command() {
: some logic not relevant to this question
eval "$@"
}
Run Code Online (Sandbox Code Playgroud)
我正在运行它:
run_command "ls" "|" "wc -l" # works, runs "ls | wc -l"
run_command "ls | wc -l" # works as above
Run Code Online (Sandbox Code Playgroud)
现在,我尝试列出一个包含空格的文件:
> "file with space"
run_command "ls" "-l" "file with space"
Run Code Online (Sandbox Code Playgroud)
这一次,我得到了这些错误:
ls: file: No such file or directory
ls: space: No such file or directory
ls: with: No such file or directory
Run Code Online (Sandbox Code Playgroud)
因此,很明显"$@"
会导致单词分裂.有没有办法防止这个问题,以便run_command
功能免受白色空间,小球和任何其他特殊字符的影响?
此命令将打印a
.
echo "line1 a b c" | awk '{ print $2 }'
Run Code Online (Sandbox Code Playgroud)
如果我将单引号更改为双引号,就像这样,它将打印整行.
echo "line1 a b c" | awk "{ print $2 }"
Run Code Online (Sandbox Code Playgroud)
为什么?我知道我应该使用单引号,但如果我使用双引号,为什么打印整行?
我正在尝试执行以下命令:
`sed 's/49%100%/49%!100%/' /etc/nagios/objects/services.cfg`
Run Code Online (Sandbox Code Playgroud)
但是我收到了这个错误
-bash: ###############################################################################: command not found
Run Code Online (Sandbox Code Playgroud)
如果我尝试在没有后退滴答的情况下运行它,该命令将起作用.
我尝试过以下方法:
`sed 's/49%100%/49%!100%/' /etc/nagios/objects/services.cfg` 2>&1
`sed 's/49%100%/49%!100%/' /etc/nagios/objects/services.cfg`> /dev/null
Run Code Online (Sandbox Code Playgroud)
但它不起作用.
我想以编程方式将小占位符替换为静态内容,如用户名或工作路径.
在bash中是否有可能动态执行我的perl替换状态,如:
GROUPNAME="$(id -g -n $USER)"
perl -pi -e 's/\(PLACEHOLDER\)/' + "$GROUPNAME" + '/g' filepath/file
Run Code Online (Sandbox Code Playgroud)
如果我还能为占位符调整这种动态行为,那将是非常好的.但首先要做的事情.如何连接这些字符串?