我试图找到并行运行多个命令的方法sh
并等待它完成.我发现以下不起作用(sh: 1: Syntax error: ";" unexpected
):
sh -c '(sleep 3 && echo 1) & ; (sleep 3 && echo 2) & ; wait'
Run Code Online (Sandbox Code Playgroud)
但是这种语法按预期工作:
sh -c '(sleep 3 && echo 1) & ;; (sleep 3 && echo 2) & ;; wait'
Run Code Online (Sandbox Code Playgroud)
但我不明白有什么区别.我的问题是;;
它应该被使用的含义是什么?
我试图在一个简单的shell脚本中比较两个字符串.我使用的是/bin/sh
代替/bin/bash
,经过无数小时的调试后,事实证明sh(实际上是破折号)无法处理这段代码:
if [ "$var" == "string" ]
then
do something
fi
Run Code Online (Sandbox Code Playgroud)
什么是比较字符串使用的可移植方式/bin/sh
?我知道我总是可以通过使用!=来做相反的事情,但我想知道一种更干净,更便携的方式.
是否有一些类似的选项dash
对应于外壳pipefail
的bash
?
或者,如果管道中的一个命令失败(但没有在其上退出,set -e
那么)获得非零状态的任何其他方式.
为了更清楚,这是我想要实现的一个例子:
在调试makefile示例中,我的规则如下所示:
set -o pipefail; gcc -Wall $$f.c -o $$f 2>&1 | tee err; if [ $$? -ne 0 ]; then vim -o $$f.c err; ./$$f; fi;
Run Code Online (Sandbox Code Playgroud)
基本上它运行会在出错时打开错误文件和源文件,并在没有错误时运行程序.给我一些打字.上面的代码段运行良好,bash
但我的新Ubunty系统使用dash
似乎不支持pipefail
选项.
如果下面一组命令的第一部分失败,我基本上想要一个FAILURE状态:
gcc -Wall $$f.c -o $$f 2>&1 | tee err
Run Code Online (Sandbox Code Playgroud)
所以我可以用它来if
表达.
有没有其他方法可以实现它?
谢谢!
谁能解释这种行为?运行:
#!/bin/sh
echo "hello world" | read var1 var2
echo $var1
echo $var2
Run Code Online (Sandbox Code Playgroud)
导致没有任何输出,而:
#!/bin/sh
echo "hello world" > test.file
read var1 var2 < test.file
echo $var1
echo $var2
Run Code Online (Sandbox Code Playgroud)
产生预期的输出:
hello
world
Run Code Online (Sandbox Code Playgroud)
管道不应该在一步中完成第二个例子中test.file的重定向吗?我用破折号和bash shell尝试了相同的代码,并从两者中获得了相同的行为.
我在实现for循环时遇到问题.我执行脚本时遇到此错误
test1.sh:2:语法错误:循环变量错误
我不明白这个错误.
这是我的剧本
#!/bin/bash
for (( c=1; c<=5; c++ ))
do
echo "Welcome $c times..."
done
Run Code Online (Sandbox Code Playgroud)
任何人都可以在ubuntu中告诉我for循环的语法(在ubuntu中它链接到破折号shell)shell吗?
我收到了这个错误
语法错误:重定向意外
在线:
if grep -q "^127.0.0." <<< "$RESULT"
Run Code Online (Sandbox Code Playgroud)
我如何在Ubuntu中运行它?
当一个类似Bash的脚本作为没有shebang的二进制文件执行时,如何以及由谁决定执行什么?
我想用 shebang 运行一个普通的脚本是用binfmt_script Linux模块处理的,它检查一个shebang,parses命令行并运行指定的脚本解释器.
但是当有人在没有shebang的情况下运行脚本时会发生什么?我已经测试了直接execv
方法并发现那里没有内核魔法 - 即像这样的文件:
$ cat target-script
echo Hello
echo "bash: $BASH_VERSION"
echo "zsh: $ZSH_VERSION"
Run Code Online (Sandbox Code Playgroud)
运行仅执行execv
调用的已编译C程序会产生:
$ cat test-runner.c void main() { if (execv("./target-script", 0) == -1) perror(); } $ ./test-runner ./target-script: Exec format error
但是,如果我从另一个shell脚本执行相同的操作,它将使用与原始shell脚本相同的shell解释器运行目标脚本:
$ cat test-runner.bash #!/bin/bash ./target-script $ ./test-runner.bash Hello bash: 4.1.0(1)-release zsh:
如果我使用其他shell执行相同的技巧(例如,Debian的默认值sh
- /bin/dash
),它也可以:
$ cat test-runner.dash #!/bin/dash ./target-script $ ./test-runner.dash Hello bash: zsh:
神秘的是,它与zsh没有达到预期的效果,并且不遵循一般方案./bin/sh
毕竟看起来像zsh 在这些文件上执行:
greycat@burrow-debian ~/z/test-runner …
我有bash脚本,它需要bash.
另一个人尝试用它来运行它
sh script_name.sh
Run Code Online (Sandbox Code Playgroud)
它失败了,因为sh是他的发行版中的破折号的象征性链接.
$ ls -la /bin/sh
lrwxrwxrwx 1 root root 4 Aug 25 16:06 /bin/sh -> dash
Run Code Online (Sandbox Code Playgroud)
我有一个想法使用包装脚本:
#!/bin/sh
bash script_name.sh
Run Code Online (Sandbox Code Playgroud)
目标是使用带有符号链接到破折号的系统中的bash运行.sh脚本.
在shell脚本中测试变量是否为空/未定义的可移植和规范方法是什么?它应该适用于所有类似sh的壳.我现在做的是:
if [ -z "$var" ] ; then
...
Run Code Online (Sandbox Code Playgroud)
而对于反向,当变量不为空/未定义时执行某些操作:
if [ -n "$var" ] ; then
...
Run Code Online (Sandbox Code Playgroud)
虽然这些对我现在编写的脚本起作用,但我想知道一种方法,它可以在任何合理兼容的sh- like shell中工作,甚至比使用GNU userland和bash或dash的Linux PC更加模糊.
我正在寻找一个在不同shell环境中经验丰富的人的"专家答案",并且知道不同做事方式的缺陷,而不是像"应该工作"这样的意见.
根据hyperpolyglot.org上的参考表,可以使用以下语法来设置数组.
i=(1 2 3)
Run Code Online (Sandbox Code Playgroud)
但我得到一个错误的破折号是/bin/sh
Ubuntu 的默认值,应该符合POSIX标准.
# Trying the syntax with dash in my terminal
> dash -i
$ i=(1 2 3)
dash: 1: Syntax error: "(" unexpected
$ exit
# Working fine with bash
> bash -i
$ i=(1 2 3)
$ echo ${i[@]}
1 2 3
$ exit
Run Code Online (Sandbox Code Playgroud)
参考表是误导性的还是错误的?
如果是,那么定义数组或列表并且符合POSIX的正确方法是什么?