我搜索了各种留言板以了解为什么在某些情况下我不能使用变量作为命令的输入。这是 STDIN 问题/限制吗?为什么使用 echo
和此处的字符串可以解决问题?
例如,
~$ myvar=$(ls -l)
~$ grep Jan "$myvar"
grep: total 9
-rwxr-xr-x 1 jvp jvp 561 Feb 2 23:59 directoryscript.sh
-rw-rw-rw- 1 jvp jvp 0 Jan 15 10:30 example1
drwxrwxrwx 2 jvp jvp 0 Jan 19 21:54 linuxtutorialwork
-rw-rw-rw- 1 jvp jvp 0 Jan 15 13:08 littlefile
-rw-rw-rw- 1 jvp jvp 0 Jan 19 21:54 man
drwxrwxrwx 2 jvp jvp 0 Feb 2 20:33 projectbackups
-rwxr-xr-x 1 jvp jvp 614 Feb 2 20:41 projectbackup.sh
drwxrwxrwx 2 jvp jvp 0 Feb 2 20:32 projects
-rw-rw-rw- 1 jvp jvp 0 Jan 19 21:54 test1
-rw-rw-rw- 1 jvp jvp 0 Jan 19 21:54 test2
-rw-rw-rw- 1 jvp jvp 0 Jan 19 21:54 test3: File name too long
如您所见,我收到错误...“文件名太长”
现在,我可以使用以下任一方式让它工作:
echo "$myvar" | grep Jan
grep Jan <<< "$myvar"
但是,我真的很想更好地理解为什么会这样。也许我遗漏了一些关于命令替换的基础知识或者什么是可接受的 STDIN 形式。
最佳答案
grep
实用程序可以操作...
- 在命令行提供名称的文件上,在用于匹配的正则表达式之后
- 在其标准输入上提供的流上。
你正在这样做:
myvar=$(ls -l)
grep Jan "$myvar"
这提供了变量 myvar
的内容作为 grep
的参数命令,因为它不是文件名,所以它不起作用。
有很多方法可以实现您的目标。这里有几个例子。
使用变量的内容作为连接到grep
的标准输入的流,使用以下方法之一(都提供相同的输出):
grep Jan <<<"$myvar"
echo "$myvar" | grep Jan
grep Jan < <(echo "$myvar")
避免以变量开头,发送ls
的输出直接到 grep :
ls -l | grep Jan
grep Jan < <(ls -l)
提供grep
使用实际上是文件名的表达式:
grep Jan <(ls -l)
<(ls -l)
表达式是导致创建 FIFO(先进先出)特殊文件的语法。 ls -l
命令将其输出发送到 FIFO。 Bash 将表达式转换为可用于读取的实际文件名。
为了消除任何混淆,下面的两个语句(已在上面显示)看起来很相似,但根本上有很大不同:
grep Jan <(ls -l)
grep Jan < <(ls -l)
在第一个中,grep
接收文件名作为参数并读取该文件。在第二种情况下,额外的 <
(两个 <
之间的空格很重要)创建一个重定向,读取 FIFO 并将其输出提供给 grep
的标准输入.两种情况下都有一个 FIFO,但它以完全不同的方式呈现给命令。
关于linux - 使用变量作为命令的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42054108/