根据我的经验,我看到的“xargs”行为似乎非常出乎意料。我使用“ls”查找匹配的文件夹名称,并使用“xargs”将其发送到“cd”。我收到该文件夹不存在的消息。但是,如果我不使用“xargs”,“cd”就可以工作。另外,如果我确实使用“xargs”但将其发送到“ls”而不是“cd”,它也可以工作。
# Identify desired directory
ls -d *[Aa]nt*
201909+ants/
# Print the desired command with "echo"
ls -d *[Aa]nt* | xargs echo cd
cd 201909+ants/
# Execute the desired command and get error
ls -d *[Aa]nt* | xargs cd
xargs: cd: No such file or directory
# Confirm that the desired command without "xargs"
cd 201909+ants # This works no problem
cd .. # Go back up
cd 201909+ants/ # This works no problem
cd .. # Go back up
# Confirm that "xargs" with "ls"
ls -d *[Aa]nt* | xargs ls -d
201909+ants/
我确信这是键盘和椅子之间的 ID1OT 问题。谁能指出我的错误在哪里?
我正在使用 Cygwin 的 Bash,但很少看到与 Linux 的差异。我不记得上次看到这样的差异是什么时候了。
答案1
工作目录是正在运行的进程的一个属性,必须在进程本身内对其进行更改。因此,cd
是 shell 中的内置命令。但xargs
不是(通常是这样),而且它不能运行 shell 内置命令。它所做的就是调用外部程序。
因为cd
它并不是真正作为外部程序工作,所以它通常在 Linux 系统上不可用。这就是您收到错误的原因。
在其他系统上可能是这样,因为某些规范说它必须如此。看为什么 cd 不是一个程序?。但它不是很有用,它只会更改进程的工作目录cd
,然后立即退出。
但是,你不需要ls
这里,或者xargs
。如果你这样做ls *.txt
或类似的话,那就是壳创建与模式匹配的文件名列表,该列表被传递给ls
,...只是将它们打印出来。和你做的几乎一样echo *.txt
。 (ls -l *.txt
会更有意义,因为在那里,ls
在查找有关文件的所有其他数据方面做了一些实际工作。)因此,ls *[Aa]nt* |xargs
您可以(大致)使用echo *[Aa]nt* | xargs
,而不是 ,这也是多余的,因为echo
打印它的命令行,xargs
并将其转换为输入进入另一个程序的命令行。
在简单的情况下,你应该能够直接使用
cd *[Aa]nt*
但是,如果该模式与多个文件名匹配,您将收到错误(或者在某些 shell 中出现奇怪的行为,例如在 ksh 中cd foo bar
对当前工作目录路径进行字符串替换。)
(当然,ls *.txt
当重定向到管道时,每行打印一个文件名,但echo *.txt
将它们全部打印在一行上,因此它们不会确切地相同。)