shell(zsh)中的echo函数和括号的捕获

The echo function in shell (zsh) and the capture of parentheses

我创建了一个小脚本,以便可以快速将一些文本附加到 Dropbox 中的文件。

代码:

#!/bin/zsh
echo $(date +%d/%m/%Y) $*>>/home/guillaume/Dropbox/note.txt

该功能按预期工作。当我在终端中输入:

$pc-guillaume$ note 123

20/01/2015 123 附加到 note.txt

但是,如果传递给 note 函数的参数中有括号,则不起作用。

例如,如果我键入:

$pc-guillaume$ note 123(

我明白了

>

如果我输入:

$pc-guillaume$ note ()

我得到:

function>

如何修改我的脚本以使其能够捕获文字括号?

用户在调用您的脚本时需要加引号:

$ note "123("

否则,您的脚本永远不会启动或 运行,因为 shell 仍在寻找用户输入——因此,出于这个原因,您无法在脚本中进行任何更改修改此行为;目前还没有得到控制。


可以做的一件事是更改调用约定。如果您的脚本是这样调用的:

$ note
123(
^D

...那么你就没有问题了。 (^D 指的是键入 ctrl+D,文件结束字符,但下面的实现也将没有输入的情况下按 enter 视为输入结束)。

您可以这样实现:

#!/bin/sh
while read -r line && [ "$line" ]; do
  printf '%s %s\n' "$(date +%d/%m/%Y)" "$line"
done >>/home/guillaume/Dropbox/note.txt

如果你不担心日期在程序运行时改变的情况 运行,你可能 运行 date 命令只执行一次,而不是吃掉效率运行每行一次。另一个优化是利用现代 shells 中的内置功能(当然 bash 4.3,不能与 zsh 对话)将日期格式化内置到 printf 而不是需要外部进程调用的开销。因此,一个利用现代 bash 功能的高效版本(仅适用于具有非常新版本 bash 的系统):

#!/bin/bash
# Warning: This requires Bash 4.3
while IFS= read -r && [[ $REPLY ]]; do
  printf '%(%d/%m/%Y)T %s\n' -1 "$REPLY"
done >>/home/guillaume/Dropbox/note.txt