use*_*291 8 bash find cd-command
当我运行此命令时,它可以工作:
$ 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
Run Code Online (Sandbox Code Playgroud)
然而,当更换ls
与cd
它不工作:
$ find . -inum 888696 -exec cd '{}' \;
find: ‘cd’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我知道cd
是一个bash
内置的,所以我想这里面确实没有任何工作:
$ find . -inum 888696 -exec builtin cd '{}' \;
find: ‘builtin’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
如何cd
与find -exec
命令一起使用?
我尝试使用cd
with的原因find -exec
是目录名称很奇怪,它在我的终端上显示为????
.
Kus*_*nda 15
执行外部实用程序的-exec
选项find
,可能带有一些命令行选项和其他参数。
您的 Unix 不cd
作为外部实用程序提供,仅作为内置 shell 提供,因此find
无法执行它。至少 macOS 和 Solaris确实提供cd
了一个外部实用程序。
cd
以这种方式执行几乎没有用处或没有用处,除非作为一种测试找到的路径名是否find
是您可以进入的目录的方法cd
。交互式 shell(或任何正在调用的find
)中的工作目录无论如何都不会改变。
有关的:
如果您遇到目录名称奇怪或极难输入的问题,并且您想切换到该目录,请考虑创建指向该目录的符号链接,然后cd
使用该链接进入该目录:
find . -inum 888696 -exec ln -s {} thedir ';'
Run Code Online (Sandbox Code Playgroud)
这将创建一个名为的符号链接thedir
,指向有问题的目录。然后您可以更改工作目录
cd thedir
Run Code Online (Sandbox Code Playgroud)
(如果链接存在于当前目录中)。这避免了以任何方式修改目录。另一个想法是以与 类似的方式重命名目录find
,但如果另一个程序希望目录具有该特定名称,则不建议这样做。
find
运行-exec
命令本身,它不涉及外壳。即使这样做了,目录的更改也只会持续到该 shell 退出,紧跟在cd
.
您需要将文件名导出到当前 shell 中才能cd
进入。根据文件名的糟糕程度,您可以使用命令替换:
cd "$(find . -inum 888696)"
Run Code Online (Sandbox Code Playgroud)
如果文件名以换行符结尾,这将不起作用,因为命令替换会占用尾随的换行符。在这种情况下,您需要保护换行符并find
在打印时去掉添加的行:
dir=$(find . -inum 888696; echo x)
cd "${dir%?x}"
Run Code Online (Sandbox Code Playgroud)
或者,使用 GNU find
,让它不打印尾随换行符(但仍保护文件名中的任何内容):
dir=$(find . -inum 888696 -printf "%px" -quit)
cd "${dir%x}"
Run Code Online (Sandbox Code Playgroud)
还使用-quit
谓词(也是 GNU 扩展),停止将第一个匹配项视为优化。
或者,您可以从内启动一个新的 shell find
,但它有点难看:
find . -inum 888696 -exec bash -c 'cd "$1" && exec bash' sh {} \;
Run Code Online (Sandbox Code Playgroud)
不是 exec,但这对你来说可能已经足够了:
cd "$(find . -inum 888696 -type d)"
Run Code Online (Sandbox Code Playgroud)
“-type d”,只是为了确定。至于什么,我真的不知道。
使用以 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
Run Code Online (Sandbox Code Playgroud)