标签: bash

为什么我的 shell 脚本会因空格或其他特殊字符而阻塞?

或者,有关强大的文件名处理和在 shell 脚本中传递的其他字符串的介绍性指南。

我写了一个 shell 脚本,它在大多数情况下运行良好。但它在某些输入(例如某些文件名)上窒息。

我遇到了如下问题:

  • 我有一个包含空格的文件名hello world,它被视为两个单独的文件helloworld.
  • 我有一个带有两个连续空格的输入行,它们在输入中缩小为一个。
  • 前导和尾随空格从输入行中消失。
  • 有时,当输入包含其中一个字符时\[*?,它们会被一些文本替换,这实际上是文件的名称。
  • 输入中有一个撇号'(或双引号"),在那之后事情变得很奇怪。
  • 输入中有一个反斜杠(或者:我使用的是 Cygwin 并且我的一些文件名具有 Windows 样式的\分隔符)。

这是怎么回事,我该如何解决?

shell bash shell-script quoting whitespace

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

如何在 bash 脚本中获取文件的大小?

如何在 bash 脚本中获取文件的大小?

我如何将它分配给一个 bash 变量,以便我以后可以使用它?

shell bash files

338
推荐指数
10
解决办法
57万
查看次数

在 bash 脚本中,在“if”语句中使用条件“or”

这个问题是我之前问题的续集。该站点上的用户帮助我确定了如何编写一个for遍历字符串值的 bash循环。例如,假设循环控制变量fname遍历字符串"a.txt" "b.txt" "c.txt"。我想echo“是的!” 何时fname具有值"a.txt"or "c.txt",并且echo“不!” 除此以外。我尝试了以下 bash shell 脚本:

#!/bin/bash

for fname in "a.txt" "b.txt" "c.txt"
do
  echo $fname
  if [ "$fname" = "a.txt" ] | [ "$fname" = "c.txt" ]; then
    echo "yes!"
  else
    echo "no!"
  fi
done
Run Code Online (Sandbox Code Playgroud)

我获得输出:

一个.txt

不!

b.txt

不!

文件

是的!

为什么该if语句在fname具有 value时显然会产生 true "a.txt"?我用|错了吗?

bash shell-script

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

如何清除 Bash 的可执行文件路径缓存?

当我在没有指定可执行文件的完整路径的情况下执行程序时,Bash 必须搜索其中的目录$PATH才能找到二进制文件,似乎 Bash 会记住某种缓存中的路径。例如,我安装了从源代码到 的 Subversion 版本/usr/local,然后svnsync help在 Bash 提示符下键入。Bash 找到了/usr/local/bin/svnsync“svnsync”的二进制文件并执行了它。然后当我删除 Subversion 中的安装/usr/local并重新运行时svnsync help,Bash 响应:

bash: /usr/local/bin/svnsync: No such file or directory
Run Code Online (Sandbox Code Playgroud)

但是,当我启动一个新的 Bash 实例时,它会找到并执行/usr/bin/svnsync.

如何清除可执行文件路径的缓存?

bash cache executable

319
推荐指数
4
解决办法
9万
查看次数

315
推荐指数
4
解决办法
8万
查看次数

如何在shell脚本中获取最后执行的命令的pid?

我想要一个这样的shell脚本:

my-app &
echo $my-app-pid
Run Code Online (Sandbox Code Playgroud)

但是我不知道如何获取刚刚执行的命令的pid。

我知道我可以只使用jobs -p my-app命令来grep pid。但是如果我想多次执行shell,这个方法就行不通了。因为工作规范是不明确的。

shell bash process background-process

311
推荐指数
2
解决办法
39万
查看次数

如何着色git的输出?

有没有办法为 git(或任何命令)的输出着色?

考虑:

baller@Laptop:~/rails/spunky-monkey$ git status
# On branch new-message-types
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   app/models/message_type.rb
#
no changes added to commit (use "git add" and/or "git commit -a")
baller@Laptop:~/rails/spunky-monkey$ git add app/models
Run Code Online (Sandbox Code Playgroud)

baller@Laptop:~/rails/spunky-monkey$ git status
# On branch new-message-types
# Changes to be committed:
#   (use "git reset HEAD <file>..." to …
Run Code Online (Sandbox Code Playgroud)

colors bash git

308
推荐指数
5
解决办法
20万
查看次数

如何在另一个 bash 会话中查看正在运行的进程的输出?

当我在本地工作时,我已经在远程机器上运行了一个脚本。我可以以同一用户身份通过​​ SSH 连接到机器,并查看在ps.

$ ps aux | grep ipcheck
myuser  18386  0.0  0.0  18460  3476 pts/0    S+   Dec14   1:11 /bin/bash ./ipchecker.sh
Run Code Online (Sandbox Code Playgroud)

它只是在本地会话上输出到标准输出(我从./ipchecker.sh本地终端窗口运行,没有重定向,没有使用screen等)。

无论如何,我可以从 SSH 会话中查看此运行命令的输出(不停止它)吗?

到目前为止,我发现的最好的方法是使用,strace -p 18386但我在屏幕上看到成群的文本,它太详细了。我可以停下来strace,然后筛选输出,发现文本带打印到标准输出,但它非常长且令人困惑,很明显,当它停止时,我可能会错过一些东西。我想找到一种方法来实时查看脚本输出,就像我在本地工作一样。

任何人都可以改进吗?显而易见的答案是通过重定向或在screen会话等中重新启动脚本,这不是关键任务脚本,所以我可以这样做。相反,我认为这是一个有趣的学习练习。

bash process io-redirection

302
推荐指数
7
解决办法
48万
查看次数

如何在 BASH 中用“cut”定义“tab”分隔符?

下面是一个cut使用空格分隔符将输入分成多个字段并获取第二个字段的示例:

cut -f2 -d' '

如何将分隔符定义为制表符而不是空格?

bash cut

300
推荐指数
4
解决办法
40万
查看次数

如何测试变量是否为空或仅包含空格?

以下 bash 语法验证是否param不为空:

 [[ !  -z  $param  ]]
Run Code Online (Sandbox Code Playgroud)

例如:

param=""
[[ !  -z  $param  ]] && echo "I am not zero"
Run Code Online (Sandbox Code Playgroud)

没有输出,很好。

但是当param除了一个(或多个)空格字符为空时,情况就不同了:

param=" " # one space
[[ !  -z  $param  ]] && echo "I am not zero"
Run Code Online (Sandbox Code Playgroud)

“我不是零”是输出。

如何更改测试以将仅包含空格字符的变量视为空?

shell bash string shell-script

290
推荐指数
5
解决办法
53万
查看次数