我已经搜索了各种留言板,以了解为什么在某些情况下我无法使用变量作为命令的输入。这是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形式。
答案 0 :(得分:2)
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,但它以与命令完全不同的方式呈现。
答案 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搜索。