$ find -exec cd =>给出错误:=> find:'cd':没有这样的文件或目录


8

当我运行此命令时,它起作用:

$ find . -inum 888696 -exec ls '{}' \;
Conversation.pst  Outlook Data File  Outlook Data File.sbd  Trash      Unsent Messages
Inbox.pst     Outlook Data File.msf  Sent.pst       Trash.msf  Unsent Messages.msf

然而,当更换lscd工作:

$ find . -inum 888696 -exec cd '{}' \;
find: cd’: No such file or directory

我知道cd是一个bash内置的,所以我想这里面确实没有任何工作:

$ find . -inum 888696 -exec builtin cd '{}' \;
find: builtin’: No such file or directory

如何cdfind -exec命令一起使用?


更新

我试图使用的原因cdfind -exec是该目录名是一个奇怪的一个,显示了我的终端,就像这样的????


1
顺便说一句,您可以LC_ALL=C printf '%q\n' *打印当前目录中所有文件的ASCII名称,一行一行地打印(将换行符更改为$'\n'类似的内容)。
查尔斯·达菲

Answers:


15

执行外部实用程序的-exec选项find,可能带有某些命令行选项和其他参数。

您的Unix不cd作为外部实用程序提供,而仅作为内置的Shell提供,因此find无法执行。至少macOS和Solaris 确实提供了cd作为外部实用程序的功能。

cd以这种方式执行几乎没有用,甚至没有用,除非是一种测试所找到的路径名是否find是您可以进入的目录的方式cd。交互式外壳程序(或任何正在调用find)中的工作目录无论如何都不会更改。

有关:


如果您遇到目录名称奇怪或很难输入的问题,并且想要更改为该目录,请考虑创建指向该目录的符号链接,然后cd使用该链接进入该目录:

find . -inum 888696 -exec ln -s {} thedir ';'

这将创建一个符号链接thedir,该链接将指向有问题的目录。然后,您可以使用

cd thedir

(如果链接存在于当前目录中)。这样可以避免以任何方式修改目录。另一个想法是使用与相似的方式来重命名目录find,但是如果另一个程序期望目录具有该特定名称,则不建议这样做。


我打算cd与之配合使用的原因find -exec是目录名称包含一些奇怪的字符,这些字符在我的终端上无法正确显示。
user3405291

@ user3405291从问题中不清楚您在运行命令时期望发生什么。您是否希望在交互式外壳中更改目录?
库萨兰达

是的,我只想cd进入一个名称不正确的目录,而我不能cd以通常的方式进入该目录。
user3405291

@ user3405291查看更新。
库萨兰达

有趣的是,这/bin/cd是POSIX(pubs.opengroup.org/onlinepubs/9699919799/utilities/…)的结果,正常的内置文件必须对exec()可用。当然,/bin/cd可能并没有满足人们的要求:-)
Stephen Harris

7

find运行-exec命令本身,它不涉及外壳。即使这样做,目录更改也将一直持续到该Shell退出后,紧接在cd

您需要将文件名移到当前shell中cd。根据文件名的严重程度,可以使用命令替换:

cd "$(find . -inum 888696)"

如果文件名以换行符结尾,那将不起作用,因为命令替换会吃掉尾随的换行符。在这种情况下,您需要保护换行符并find在打印时摆脱添加的内容:

dir=$(find . -inum 888696; echo x)
cd "${dir%?x}"

或者,使用GNU时find,不要打印尾随的换行符(但仍保护文件名中的任何换行符):

dir=$(find . -inum 888696 -printf "%px" -quit)
cd "${dir%x}"

还使用-quit谓词(也是GNU扩展)来停止照看第一场比赛。

另外,您可以从中启动一个新的shell find,但这有点难看:

find . -inum 888696 -exec bash -c 'cd "$1" && exec bash' sh {} \;

在换行符,回车符和两者都以失败结尾的目录上使用“ echo x”尝试了技巧。
Gerard H. Pille,

@ GerardH.Pille,哦,对不起,我忘了换行find本身在打印时会添加。编辑。
ilkkachu

如果将printf替换为print0,则可以执行'cd“ $ dir”'。
Gerard H. Pille

@ GerardH.Pille,也许。但是Bash会忽略命令替换输入中的任何nul字节,并仅在此之后删除尾随的换行符。因此,dir=$(find -print0)仍然会
删除

5

不能与exec一起使用,但这对您可能已经足够了:

cd "$(find . -inum 888696 -type d)"

可以肯定的是,“类型d”。我什么都不知道。


如果目录名称以换行符结尾,则此操作将失败。
库萨兰达

可以,但是目录很少这样做。如果我尝试在linux ext4上创建一个,则会出现“协议错误”。您不是在浪费时间吗?
Gerard H. Pille

2
好吧,名字很少有无法打印的字符,但是这一点显然可以做到。
库萨兰达

哪些文件系统允许目录名称中使用换行符?
Gerard H. Pille

1
@ GerardH.Pille,您如何测试的?mkdir $'foo\n'在这里工作完美;我还没有看到支持它的本地UNIX文件系统。
查尔斯·达菲

4

使用以NUL分隔的流来读取find所有情况下有效的输出-包括以换行符结尾的名称。同样,您可以printf '%q'用来生成文件名的可读表示。

inum=888696
if IFS= read -r -d '' filename < <(find . -inum "$inum" -print0); then
  LC_ALL=C printf 'Located filename: %q\n' "$filename" >&2
  cd -- "$filename"
else
  echo "No file located for inode $inum" >&2
fi

3

如果收到此消息,则说明您的OS平台存在问题。POSIX标准要求cd在文件系统中必须有一个名为的命令,因此可以通过调用该命令exec()

现在对您来说是个坏消息:

即使您的OS平台不是错误的,您也只是没有看到警告,而是没有得到预期的结果,因为如果一个单独的程序更改了其当前的工作目录并在此之后立即死去,它不会为您提供帮助。

如果您希望对所cd执行的命令有效find,则可以执行以下操作:

find . -type d -exec sh -c 'cd "$1"; some other command' dummy {} \;

2
如果该平台声称符合POSIX,那只是一个错误。拥有独立的cd实用程序不是很有用,因此可以忽略该要求,而又不影响平台的可用性。请注意,在中sh,不使用引号扩展参数具有非常特殊的含义,而不是您想要执行的操作。最好避免在错误消息中使用该内嵌脚本的$0(例如,当cd失败时)。
斯特凡Chazelas

你是说cd "$1"吗 如果名称很难输入,它也可能包含壳元字符...
Toby Speight,

纠正,这是一个错字
schily
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.