2

在 zsh 中运行如下所示的循环会在输出中出现空行(忽略此循环的琐碎性;这只是一个示例。一个更现实的示例可能是运行mysql -s -e "show databases;"并为每个数据库执行某些操作)。

for foo in $(cat test.txt); do
    echo $foo
done



alpha
bravo
charlie
delta

在此示例中,如果test.txt有四行,则会出现三个空白行。如果它有五行,则会出现四个空白行。在我的 MySql 示例中,空白行将比 MySql 数据库少一个。

是什么导致这些空白行,我该如何防止它们?在 Bash 中运行相同的脚本不会给出空行。


编辑:看起来 Oh My Zsh 是罪魁祸首,虽然我还没有弄清楚原因。source $ZSH/oh-my-zsh.sh如果我在 中注释掉.zshrc,则不再出现空行。

4

2 回答 2

3

所以是的,~/.oh-my-zsh 是罪魁祸首。进入 ~/.oh-my-zsh/lib/termsupport.zsh

#Appears at the beginning of (and during) of command execution
function omz_termsupport_preexec {
  emulate -L zsh
  setopt extended_glob
  local CMD=${1[(wr)^(*=*|sudo|ssh|rake|-*)]} #cmd name only, or if this is sudo or ssh, the next cmd
  local LINE="${2:gs/$/\\$}"
  LINE="${LINE:gs/%/%%}"
  title "$CMD" "%100>...>$LINE%<<"
}

我们看到它试图将标题设置为整个命令,包括命令之后的内容,去掉 sudo 之类的前缀,并对 $ 和 % 之类的字符进行一些转义。但是由于某种原因,当你做一只猫时,它会抛出一些换行符。为了快速解决问题,我只是将标题设置为 $CMD 有点笨拙,如下所示:

#Appears at the beginning of (and during) of command execution
function omz_termsupport_preexec {
  emulate -L zsh
  setopt extended_glob
  local CMD=${1[(wr)^(*=*|sudo|ssh|rake|-*)]} #cmd name only, or if this is sudo or ssh, the next cmd
  ## Removing command argument parsing because of cat bug
  #local LINE="${2:gs/$/\\$}"
  #LINE="${LINE:gs/%/%%}"
  #title "$CMD" "%100>...>$LINE%<<"
  title "$CMD" 
}

我已经在 oh-my-zsh 的 github 上回顾了这个文件的最新历史,但似乎这个错误已经存在了一段时间。“正确”的答案可能是围绕 $LINE 进行一些嵌套扩展,以删除空白和换行符并向 oh-my-zsh 发出拉取请求。但是我的 zsh foo 仍然太弱了。

于 2013-09-24T23:55:07.750 回答
-1

我会假设 Bash 以某种方式完全过滤掉了空白。一个简单的解决方法是 grep 一点。

例子:

for foo in $(grep -v '^$' test.txt); do
    # The quotes are recommended to make sure you shell won't do weird things with the variables
    echo "$foo"
done
于 2013-05-28T13:24:17.817 回答