标签: dash

尽管语法错误,Shell 脚本仍返回 0 exit_status

考虑这个脚本:

#!/bin/sh

foo=1
if [[ ! -z $foo ]]; then
    echo abc
fi
Run Code Online (Sandbox Code Playgroud)

它使用 Bash 语法 [[ ... ]] 当我在 Ubuntu (dash) 上使用默认 shell 运行它时,它不起作用(如预期)。但是,它的返回码仍然为零。

$ ./tmp.sh
./tmp.sh: 4: ./tmp.sh: [[: not found
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)

如果我不能依赖退出代码,如何在脚本中检测这种错误?

shell dash exit-status

10
推荐指数
2
解决办法
461
查看次数

相当于脚本输出自重定向的破折号

在 Bash 中,您可以重定向当前正在运行的脚本的所有未来stdout 输出。例如使用这个脚本,

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3
Run Code Online (Sandbox Code Playgroud)

这将在系统日志中结束:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3
Run Code Online (Sandbox Code Playgroud)

但这是 Bash 特定的,带有重定向的裸 exec 在 Dash 中似乎不起作用。

Syntax error: redirection unexpected
Run Code Online (Sandbox Code Playgroud)

我怎样才能让它在 Dash 中工作,或者可能在两个 shell 中工作?

io-redirection dash shell-script process-substitution

9
推荐指数
2
解决办法
3303
查看次数

在 dash vs ksh 和 bash 中退出陷阱

这是一个简单的脚本,它在当前目录中设置一个临时目录,并在退出时设置一个陷阱以将其删除。

#filename: script   
set -x  
trap 'rm -rf "$d"' exit
d=`TMPDIR=$PWD mktemp -d`
"$@"
Run Code Online (Sandbox Code Playgroud)

如果我执行ksh script sleep 100bash script sleep 100中断它C-C,则执行陷阱并删除目录。它不适用于dash. 为什么?这是错误还是预期行为?

bash ksh dash trap

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

bash 文件重定向到标准 in 与 Linux 上的 shell (`sh`) 有何不同?

我写了一个脚本,它在运行时切换用户,并使用文件重定向到标准输入来执行它。所以user-switch.sh是......

#!/bin/bash

whoami
sudo su -l root
whoami
Run Code Online (Sandbox Code Playgroud)

并运行它bash给了我我期望的行为

$ bash < user-switch.sh
vagrant
root
Run Code Online (Sandbox Code Playgroud)

但是,如果我用 运行脚本sh,我会得到不同的输出

$ sh < user-switch.sh 
vagrant
vagrant
Run Code Online (Sandbox Code Playgroud)

为什么bash < user-switch.sh给出的输出与sh < user-switch.sh?

笔记:

  • 发生在运行 Debian Jessie 的两个不同的机器上

bash io-redirection dash stdin

9
推荐指数
2
解决办法
1424
查看次数

在 /bin/sh 中的冒号上拆分字符串

我的dash脚本采用 形式的参数hostname:port,即:

myhost:1234
Run Code Online (Sandbox Code Playgroud)

而端口是可选的,即:

myhost
Run Code Online (Sandbox Code Playgroud)

我需要将主机和端口读入单独的变量。在第一种情况下,我可以这样做:

HOST=${1%%:*}
PORT=${1##*:}
Run Code Online (Sandbox Code Playgroud)

但这在第二种情况下不起作用,当端口被省略时;echo ${1##*:}只返回主机名,而不是空字符串。

在 Bash 中,我可以这样做:

IFS=: read A B <<< asdf:111
Run Code Online (Sandbox Code Playgroud)

但这在dash.

能否在拆分字符串:在仪表板,而无需调用外部程序(awktr,等)?

shell dash string

9
推荐指数
2
解决办法
5382
查看次数

在脚本中,检查标准输入是否来自文件或管道

我知道以前对此的报道很少,但这些答案要么缺乏解释,要么不适用。

基本上在某些时候,我的脚本需要检查是否指定了文件,如果是,则稍后将用作输入。

[ -f "$1" ] && TINPUT="$1"
Run Code Online (Sandbox Code Playgroud)

足够简单......现在如果找不到文件或未指定文件,我TINPUT="-"会告诉后面的命令读取标准输入。

这是我的问题......如果脚本在没有管道或没有指定文件的情况下运行,我如何让脚本因错误而死?

我正在使用 dash,Debian POSIX 兼容 shell,所以我不能使用 Bashisms。我也更喜欢使用列表,ifs但大多数ifs都可以写在列表中。

shell dash shell-script stdin

8
推荐指数
1
解决办法
2687
查看次数

为什么使用嵌套命令的存储返回码退出会导致 Dash 和 Bash 中的返回码不同?

跑步

bash -c 'bash -c "echo test1; exit 1;" &> /tmp/x; buildresult=$?; tail -n 100 /tmp/x; exit $buildresult;'
Run Code Online (Sandbox Code Playgroud)

结果test1被打印到控制台并echo $?打印1在我的理解中是正确的,因为命令应该返回内部[b/d]ash -c返回的内容,而

dash -c 'dash -c "echo test1; exit 1;" &> /tmp/x; buildresult=$?; tail -n 100 /tmp/x; exit $buildresult;'
Run Code Online (Sandbox Code Playgroud)

导致相同的输出,但0根据返回echo $?

我想了解这种差异,以拓宽我对 shell 和可移植 shell 编程的理解。

我在 Ubuntu 17.10 (Artful Aardvark) 上使用bash4.4.12 和dash0.5.8-2.3ubuntu1。

shell bash dash subshell exit-status

8
推荐指数
1
解决办法
486
查看次数

测试变量是否包含换行符 (POSIX)

我知道有些 shell 接受这种测试:

t() { [[ $var == *$'\n'* ]] && res=yes || res=no
      printf '%s ' "$res";
    }

var='ab
cd'
t
var='abcd'
t
echo
Run Code Online (Sandbox Code Playgroud)

执行时:

$ bash ./script
yes no
Run Code Online (Sandbox Code Playgroud)
  1. 什么是 POSIX(破折号)工作等效项

  2. 以下是可靠的测试方法吗?

    nl='
    '
    
    t() {  case "$var" in
               *$nl* ) res=yes ;;
               * ) res=no ;;
           esac
           printf '%s ' "$res"
         }
    
    var='ab
    cd'
    t
    var='abcd'
    t
    echo
    
    Run Code Online (Sandbox Code Playgroud)

shell dash string posix newlines

8
推荐指数
2
解决办法
2550
查看次数

sh shell 不支持 $@ 上的参数扩展吗?

我在 AU 上发布一个问题的答案,我发现参数扩展 on$@不适用于shshell:

<infile xargs -d'\n' sh -c 'echo "${@%%/*}"' _
Run Code Online (Sandbox Code Playgroud)

但它在bash. 这是shshell 的预期行为,我如何在那里执行扩展?

此外,我知道通过-n1选项xargs我一次只能将一行传递给命令,但我对是否sh可以扩展感兴趣$@

<infile xargs -d'\n' -n1 sh -c 'echo "${0%%/*}"'
Run Code Online (Sandbox Code Playgroud)

infile 包含:

A1 /B1/C1
A 2/B2/C2
A3/B3/C3
Run Code Online (Sandbox Code Playgroud)

shell bash dash

8
推荐指数
1
解决办法
855
查看次数

便携查空目录

使用 Bash 和 Dash,您可以仅使用 shell 检查空目录(忽略点文件以保持简单):

set *
if [ -e "$1" ]
then
  echo 'not empty'
else
  echo 'empty'
fi
Run Code Online (Sandbox Code Playgroud)

但是我最近了解到 Zsh 在这种情况下失败了:

% set *
zsh: no matches found: *

% echo "$? $#"
1 0
Run Code Online (Sandbox Code Playgroud)

所以不仅set命令失败,而且它甚至没有设置$@. 我想我可以测试 if $#is 0,但似乎 Zsh 甚至停止执行:

% { set *; echo 2; }
zsh: no matches found: *
Run Code Online (Sandbox Code Playgroud)

与 Bash 和 Dash 比较:

$ { set *; echo 2; }
2
Run Code Online (Sandbox Code Playgroud)

这可以以在 bash、dash 和 zsh …

bash zsh dash wildcards portability

8
推荐指数
2
解决办法
1919
查看次数