2

我正在使用 Mac OS X 的pbpaste命令,它返回剪贴板的内容。我想创建一个 shell 脚本,将返回的每一行pbpaste作为单独的 bash 命令执行。例如,假设剪贴板的内容由以下几行文本组成:

echo 1234 >~/a.txt
echo 5678 >~/b.txt

我想要一个执行每一行的 shell 脚本,在我的主文件夹中创建两个文件 a.txt 和 b.txt。经过大量的搜索和反复试验,我已经到了能够while使用以下构造将单独的文本行分配给循环中的变量的地步:

pbpaste | egrep -o [^$]+ | while read l; do echo $l; done

正如预期的那样,它将以下内容发送到标准输出:

echo 1234 >~/a.txt
echo 5678 >~/b.txt

然后我尝试使用以下构造执行它们,而不是简单地回显每一行文本:

pbpaste | egrep -o [^$]+ | while read l; do $l; done

我认为这将执行每一行(从而在我的主文件夹中创建两个文本文件 a.txt 和 b.txt)。echo相反,第一项nnnn >~/...

1234 >~/a.txt
5678 >~/b.txt

在理解为什么我的构造不起作用以及哪些更改可能使其起作用方面,我将不胜感激。

4

1 回答 1

2

[…] the remaining terms (nnnn >~/...) seem to get lumped together as if they were a single parameter, […]

Not exactly. The line actually gets split on whitespace (or whatever $IFS specifies), but the problem is that the redirection operator > cannot be taken from a shell variable. For example, this snippet:

gt='>'
echo $gt foo.txt

will print > foo.txt, rather than printing a newline to foo.txt.

And you'll have similar problems with various other shell metacharacters, such as quotation marks.

What you need is the eval builtin, which takes a string, parses it as a shell command, and runs it:

pbpaste | egrep -o [^$]+ | while IFS= read -r LINE; do eval "$LINE"; done

(The IFS= and -r and the double-quotes around $LINE are all to prevent any other processing besides the processing performed by eval, so that e.g. whitespace inside quotation marks will be preserved.)

Another possibility, depending on the details of what you need, is simply to pipe the commands into a new instance of Bash:

pbpaste | egrep -o [^$]+ | bash

Edited to add: For that matter, it occurs to me that you can pass everything to eval in a single batch; just as you can (per your comment) write pbpaste | bash, you can also write eval "$(pbpaste)". That will support multiline while-loops and so on, while still running in the current shell (useful if you want it to be able to reference shell parameters, to set environment variables, etc., etc.).

于 2013-01-31T23:09:25.147 回答