使用变量作为命令的输入

时间:2017-02-05 15:57:33

标签: 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形式。

3 个答案:

答案 0 :(得分:2)

grep实用程序可以运行...

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

    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,但它以与命令完全不同的方式呈现。

答案 1 :(得分:1)

我认为对Unix工具/ Bash如何在这里运作存在根本性的误解。

您在此处尝试执行的操作是将ls的输出存储在变量中(这是您不应该因其他原因而做的事情)并尝试{{1}使用grep。

跨越存储在该变量中的字符串

这不是grep的工作原理。如果你看man page for grep,就会说:

grep

请注意,它具体说&#34; grep搜索指定的输入 FILEs &#34;。 然后继续说&#34; 如果没有指定文件[...] grep搜索标准输入&#34;。

换句话说,根据定义,SYNOPSIS grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...] DESCRIPTION grep searches the named input FILEs for lines containing a match to the given PATTERN. If no files are specified, or if the file “-” is given, grep searches standard input. By default, grep prints the matching lines. 不会搜索字符串。它搜索文件。因此,您无法通过bash变量传递grep字符串。

键入

grep

根据语法,grep认为&#34; Jan&#34;是&#34; $ myvar&#34;中的PATTERN和整个字符串。是一个文件名。因此错误grep Jan "$myvar"

写作时

File name too long

你现在正在做的是使bash输出&#34; $ myvar&#34;到标准输出。 bash中的echo "$myvar" | grep Jan (管道运算符)将|命令的 stdout (标准输出)连接到 stdin (标准输入) echo命令。如上所述,当您将FILEname参数省略为grep时,默认情况下会在其中搜索 stdin 中的字符串,这就是为什么会这样做的原因。

答案 2 :(得分:0)

Grep采用命令行参数文件,而不是直接字符串。确实需要echo在变量中进行grep搜索。