linux - 使用变量作为命令的输入

标签 linux bash variables stdin

我搜索了各种留言板以了解为什么在某些情况下我不能使用变量作为命令的输入。这是 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实用程序可以操作...

  1. 在命令行提供名称的文件上,在用于匹配的正则表达式之后
  2. 在其标准输入上提供的流上。

你正在这样做:

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/

相关文章:

linux - bash 提示不显示行首

javascript - SharePoint 2010 Jquery/JSON Rest 多个 OR 语句 - 如何?

php - 传递给函数的原始变量名?

linux - 以顺序方式处理并发作业

Bash将文件移动到同名文件夹

linux - 在端口 10334 连接到定位器的第二个 geode 容器的问题

java - 如何从同一项目中的另一个类访问主类的变量?

c++ - Qt框架使用ffmpeg库报错

linux - 剪切命令ubuntu

java - 在具有 maven 依赖项的 linux 命令中运行 java 文件