“xargs”不通过 stdio 向“cd”发送参数

“xargs”不通过 stdio 向“cd”发送参数

根据我的经验,我看到的“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将它们全部打印在一行上,因此它们不会确切地相同。)

相关内容