相关疑难解决方法(0)

为什么 ( exit 1 ) 不退出脚本?

我有一个脚本,当我想要它时它不会退出。

具有相同错误的示例脚本是:

#!/bin/bash

function bla() {
    return 1
}

bla || ( echo '1' ; exit 1 )

echo '2'
Run Code Online (Sandbox Code Playgroud)

我假设会看到输出:

:~$ ./test.sh
1
:~$
Run Code Online (Sandbox Code Playgroud)

但我实际上看到:

:~$ ./test.sh
1
2
:~$
Run Code Online (Sandbox Code Playgroud)

()命令链是否以某种方式创建了一个范围?exit如果不是脚本,退出是什么?

shell-script exit subshell

60
推荐指数
3
解决办法
5万
查看次数

为什么我的变量在一个“while read”循环中是局部变量,而在另一个看似相似的循环中却不是?

为什么我$x从下面的片段中得到不同的值?

#!/bin/bash

x=1
echo fred > junk ; while read var ; do x=55 ; done < junk
echo x=$x 
#    x=55 .. I'd expect this result

x=1
cat junk | while read var ; do x=55 ; done
echo x=$x 
#    x=1 .. but why?

x=1
echo fred | while read var ; do x=55 ; done
echo x=$x 
#    x=1  .. but why?
Run Code Online (Sandbox Code Playgroud)

pipe shell-script variable-substitution variable

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

错误:将输出传输到命令时重定向不明确

在脚本中重定向的输出:

$ ls -ltr |awk '{print $9}'

default.txt
dfah.txt
fruit.txt
fruit_prices.txt
dfh.txt
header.txt
testfile.txt
topoutput.txt
Run Code Online (Sandbox Code Playgroud)

在 shell 上编写的脚本:

while read line
do 
var=`sed -e 's/\.txt/txt\.txt/' $line`
 echo $var
 done < `ls -ltr |awk '{print $9}'`
Run Code Online (Sandbox Code Playgroud)

出现错误:

-bash: `ls -ltr |awk '{print $9}'`: ambiguous redirect
Run Code Online (Sandbox Code Playgroud)

专家可以帮我看看上面的代码中如何发生不明确的重定向吗?

awk shell-script text-processing

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

为什么我必须在使用管道时将读取的命令放入子shell

该命令df .可以向我们显示我们在哪个设备上。例如,

me@ubuntu1804:~$ df .
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sdb1       61664044 8510340  49991644  15% /home
Run Code Online (Sandbox Code Playgroud)

现在我想得到字符串/dev/sdb1

我这样试过,但没有用:df . | read a; read a b; echo "$a",这个命令给了我一个空的输出。但df . | (read a; read a b; echo "$a")会按预期工作。

我现在有点困惑。

我知道这(read a; read a b; echo "$a")是一个子shell,但我不知道为什么我必须在这里制作一个子shell。据我了解,x|y会将 的输出重定向xy. 为什么read a; read a b; echo $a不能获得输入但子外壳可以?

bash pipe subshell read

5
推荐指数
1
解决办法
467
查看次数

如何单次获取字节数和 sha1sum?

我想获取命令输出的字节数和 sha1sum。

\n

原则上,人们总是可以做这样的事情:

\n
BYTES="$( somecommand | wc -c )"\nDIGEST="$( somecommand | sha1sum | sed 's/ .*//' )"\n
Run Code Online (Sandbox Code Playgroud)\n

...但是,对于我感兴趣的用例,somecommand相当耗时,并且会产生大量输出,所以我宁愿只调用它一次。

\n

我想到的一种方法是这样的

\n
evil() {\n  {\n    somecommand | \\\n      tee >( wc -c | sed 's/^/BYTES=/' ) | \\\n      sha1sum | \\\n      sed 's/ .*//; s/^/DIGEST=/'\n  } 2>&1\n}\n\neval "$( evil )"\n
Run Code Online (Sandbox Code Playgroud)\n

...这似乎有效,但让我内心有点死了。

\n

我想知道是否有更好(更稳健、更通用)的方法来将管道不同段的输出捕获到单独的变量中。

\n

编辑:我目前正在解决的问题是bash,所以我最感兴趣的是这个 shell 的解决方案,但我也做了很多zsh编程,所以我对这些解决方案也有一些兴趣。

\n

EDIT2:我尝试将 St\xc3\xa9phane Chazelas 的解决方案移植到bash,但它不太有效:

\n
#!/bin/bash\n\ncmd() {\n    printf -- '%1000s'\n}\n\nbytes_and_checksum() {\n …
Run Code Online (Sandbox Code Playgroud)

bash zsh shell-script

4
推荐指数
1
解决办法
579
查看次数

如何从标准输入读取“读取”?

read 据说bash 内置命令接受来自 stdin 的输入,但为什么以下没有读取任何内容?

$ printf "%s" "a   b" | read line
$ printf "%s" "$line"
$
Run Code Online (Sandbox Code Playgroud)

谢谢。

bash read

3
推荐指数
1
解决办法
1961
查看次数

追加到循环内的全局变量?

我有一个全局变量$EMAIL。我想遍历几个文件,对于每个符合条件的文件,我都会将其添加到$EMAIL报告生成中。

问题是当我$EMAIL在循环内重新定义时,它只会$EMAIL在循环迭代的范围内发生变化。的全球版本$EMAIL仍然是空的。

这是我的程序的简化版本:

#!/usr/bin/env bash

EMAIL="I echo without 'nope'"
ls | while read line; do
  if [ 73523 -lt 86400 ]
  then
    echo "Hasn't been backed up in over a day"
    EMAIL="$EMAIL nope"
  fi
done

echo $EMAIL
Run Code Online (Sandbox Code Playgroud)

如何修改我的脚本以便我可以$EMAIL从循环内部添加?


编辑/更新

我想进一步简化这个例子,所以我尝试改变

ls | while read line; do
Run Code Online (Sandbox Code Playgroud)

到:

for i in {1..2}; do
Run Code Online (Sandbox Code Playgroud)

奇怪的是,此更改nope附加到$EMAIL,也许我误解了这里出了什么问题?

bash

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

破折号:从管道读取变量

bashor 中zsh,我可以使用以下语法从管道读取到变量:

echo AAA BBB | read X Y ; echo $X
Run Code Online (Sandbox Code Playgroud)

这将打印 AAA

为什么同样不起作用/bin/sh

我在 Debian 中使用/bin/sh-> /bin/dash dash

shell dash

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

zsh 随机生成器中的奇怪行为

我有这个脚本从定义的字符列表中生成 $1 位的混合随机字符作为数组。

#!/bin/bash

charlist1=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
charlist2=(0 1 2 3 4 5 6 7 8 9)
charlists=(${charlist1[*]} ${charlist2[*]})

i="1"
while [ $i -le $1 ]; do
    out=$out`echo -n ${charlists[$(($RANDOM % ${#charlists[*]}))]}`
    i=$(( i + 1 ))
done

echo $out
Run Code Online (Sandbox Code Playgroud)

它在 bash 中运行良好,但是如果我用 zsh 调用它,zsh that_script_above.sh 6它只会生成 6 位相同字符的数字,如下所示:

>>> zsh that_script_above.sh 6
llllll
>>> …
Run Code Online (Sandbox Code Playgroud)

zsh random command-substitution subshell

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