这个问题可能听起来有点愚蠢,但我真的看不出重定向和管道之间的区别。
重定向用于重定向 stdout/stdin/stderr,例如ls > log.txt.
管道用于将命令的输出作为另一个命令的输入,例如ls | grep file.txt.
但是为什么同一件事有两个运营商呢?
为什么不直接写ls > grep来传递输出,这不也是一种重定向吗?我缺少什么?
例如,
假设我想列出一个文件夹的内容,并直接将它们粘贴到聊天窗口中供朋友查看。
我意识到我可以ls > filename.txt用这些内容创建一个文件 (filename.txt);然后我必须打开或打印文件并手动选择和复制文本块(这可能很烦人/乏味。)我显然也可以ls直接从终端窗口中选择和复制输出。
简单地将标准输出通过管道传输到剪贴板会更快/更容易。
什么终端命令允许我这样做?
我最近阅读了命名管道,但我不明白它们为什么存在。
我在某处读到使用命名管道比使用文件更省时。
为什么会这样?
命名管道也必须存储在内存中(可能会被交换,就像文件一样)。
据我所知,他们必须获得一个必须由当前目录引用的 inode,就像文件一样。此外,它们必须由程序员删除,就像文件一样。
那么优势在哪里呢?
我正在处理一个计算量很大的代码 - 目前 - 崩溃了很多,但我仍在努力:) 当它崩溃时,我无法关闭 GUI 窗口;我必须打开一个 shell 并杀死 -9 进程。
它是一个Java进程,很容易找到:
nkint@zefiro:~$ ps aux | grep java
nkint 2705 16.6 1.0 460928 43680 ? Sl 12:23 0:08 /usr/lib/jvm/java-6-sun-1.6.0.26/bin/java -Djava.library.path=something something
nkint 2809 0.0 0.0 4012 776 pts/0 S+ 12:24 0:00 grep --color=auto java
nkint@zefiro:~$ kill -9 2705
Run Code Online (Sandbox Code Playgroud)
现在这很容易,但相当机械的任务。所以通常我会等待大约 7-8 个进程崩溃,然后kill -9每个进程崩溃。
我想以自动方式执行此操作。我认为应该很容易通过管道传输一些命令来获取 (n-1) 个结果的 idps aux | grep java并杀死它,但我不知道从哪里开始。
谁能给我任何提示?
我一直在研究命令行并了解到|(pipeline) 旨在将命令的输出重定向到另一个命令的输入。那么为什么命令ls | file不起作用呢?
file 输入是多个文件名之一,例如 file filename1 filename2
ls输出是文件夹上的目录和文件列表,所以我认为ls | file应该显示文件夹上每个文件的文件类型。
但是,当我使用它时,输出是:
Usage: file [-bcEhikLlNnprsvz0] [--apple] [--mime-encoding] [--mime-type]
[-e testname] [-F separator] [-f namefile] [-m magicfiles] file ...
file -C [-m magicfiles]
file [--help]
Run Code Online (Sandbox Code Playgroud)
由于file命令的使用存在一些错误
当我输入以下内容时:
find . -name *foo* | ls -lah
Run Code Online (Sandbox Code Playgroud)
它返回与普通ls命令相同的结果,就好像它没有输入一样。
然而:
ls -lah $( find . -name *foo* )
Run Code Online (Sandbox Code Playgroud)
效果很好,但只有当find命令有结果时。
是否可以通过管道传输ls?
这就是我登录 FTP 时正在做的事情:
ftp user:password@server
ftp: user:password@server: Unknown host
ftp> echo HELLO WORLD!
ftp> quit
Run Code Online (Sandbox Code Playgroud)
我想做一个单行 FTP 命令...
ftp user:password@server -command "echo HELLO WORLD"
Run Code Online (Sandbox Code Playgroud)
或者
"echo HELLO WORLD" | ftp user:password@server
Run Code Online (Sandbox Code Playgroud)
类似的东西......作为我正在尝试创建的脚本的一部分。没有传输任何内容,我只需要回显一些指令,这是我发现在我的两个系统之间执行此操作的最简单方法。
我有一个带有-i标志的输入的脚本。我的输入文件是压缩的 (.gz)。我想要做什么(不确定是否可能),因为文件很大,请执行以下操作:
gunzip -c myfile.gz | myScript.pl -i STDIN -o myoutfile.txt
Run Code Online (Sandbox Code Playgroud)
因此,将解压的输出通过管道传输到我的脚本输入标志。
我有一个 bash 脚本,它在一次执行之前根据一些参数在字符串中构建一个命令行。连接到命令字符串的部分应该由管道分隔,以促进通过每个组件的数据“流”。
一个非常简单的例子:
#!/bin/bash
part1=gzip -c
part2=some_other_command
cmd="cat infile"
if [ ! "$part1" = "" ]
then
cmd+=" | $part1"
fi
if [ ! "$part2" = "" ]
then
cmd+=" | $part2"
fi
cmd+="> outfile"
#show command. It looks ok
echo $cmd
#run the command. fails with pipes
$cmd
Run Code Online (Sandbox Code Playgroud)
出于某种原因,管道似乎不起作用。当我运行这个脚本时,我收到不同的错误消息,通常与命令的第一部分(在第一个管道之前)有关。
所以我的问题是是否可以以这种方式构建命令,最好的方法是什么?
我正在尝试从给定的 URL下载一些.gz文件(注意不是文件.tar.gz)并解压缩它们以覆盖现有文件(如果有)。
对于每个单独的下载,我尝试了以下操作:
curl -O $URL | gunzip -f
Run Code Online (Sandbox Code Playgroud)
然而,这并没有工作,因为它与失败:gzip: stdin: unexpected end of file。我在 bash shell 脚本中运行了一系列此命令。
如果我将命令分成两个明确的步骤,即首先下载文件,然后解压缩.gz文件,它就可以工作。
为什么管道版本不起作用?