[英]Bash find command : No such file or directory
This one is stumping me quite well!这个让我很难过! Big points for a resolution!
一个决议的大点!
I need to traverse a directory and all levels below it to discover any files or directories that do not match a pattern.我需要遍历目录及其下的所有级别,以发现与模式不匹配的任何文件或目录。
I'm using find command -我正在使用查找命令 -
find -L /home/user/inbox \( ! -path /home/user/inbox -a ! -path '/home/user/inbox/*' -a ! -path /home/user/inbox/imaging -a ! -path '/home/user/inbox/imaging/*' \) -ls
The error -错误 -
find -L /home/user/inbox \( ! -path /home/user/inbox -a ! -path '/home/user/inbox/*' -a ! -path /home/user/inbox/imaging -a ! -path '/home/user/inbox/imaging/*' \) -ls: No such file or directory
Yes, each of those directories in the find command do indeed exist -是的, find 命令中的每个目录确实存在 -
ls -ld /home/user/inbox /home/user/inbox/imaging/
drwxr-xr-x. 5 user grp-ftp-admin 8192 Jan 13 12:45 /home/user/inbox
drwxr-xr-x. 3 user grp-ftp-admin 152 Jan 13 12:21 /home/user/inbox/imaging/
The entire script source -整个脚本源——
#!/usr/bin/env bash
function findInvalidArtifacts() {
unset inbox sshCommand exitCode cmdOutput
s ilocal -A VENDOR=(
['FTPBASE']="/home/user"
['FTPSOURCEDIR']="/home/user/inbox/imaging"
['FRIENDLYNAME']="user"
['ENVIRONMENT']="dev"
)
inbox="${VENDOR['FTPBASE']}/inbox"
printf -v sshCommand "find -L %s \( ! -path %s -a ! -path '%s/*' -a ! -path %s -a ! -path '%s/*' \) -ls" \
"${inbox}" "${inbox}" "${inbox}" "${VENDOR['FTPSOURCEDIR']}" "${VENDOR['FTPSOURCEDIR']}"
#cmdOutput=$(ssh ${SSHOPTIONS} ${SSHUSERHOST} "${sshCommand}" 2>&1)
cmdOutput=$("${sshCommand}")
exitCode="${?}"
if (( 0 != $exitCode )); then
printf "FAILED - sshCommand=[%s], exitCode=[%d], cmdOutput=[%s]\n" "${sshCommand}" "${exitCode}" "${cmdOutput}"
exit 1
fi
printf "SUCCEEDED - sshCommand=[%s] exitCode=[%d]\n" "${sshCommand}" "${exitCode}"
printf "%s\n\n" "${cmdOutput}"
} # end findInvalidArtifacts()
And, finally, running the script with bash -vx -最后,使用 bash -vx - 运行脚本
#!/usr/bin/env bash
function findInvalidArtifacts() {
unset inbox sshCommand exitCode cmdOutput
local -A VENDOR=(
['FTPBASE']="/home/user"
['FTPSOURCEDIR']="/home/user/inbox/imaging"
['FRIENDLYNAME']="user"
['ENVIRONMENT']="dev"
)
inbox="${VENDOR['FTPBASE']}/inbox"
printf -v sshCommand "find -L %s \( ! -path %s -a ! -path '%s/*' -a ! -path %s -a ! -path '%s/*' \) -ls" \
"${inbox}" "${inbox}" "${inbox}" "${VENDOR['FTPSOURCEDIR']}" "${VENDOR['FTPSOURCEDIR']}"
#cmdOutput=$(ssh ${SSHOPTIONS} ${SSHUSERHOST} "${sshCommand}" 2>&1)
cmdOutput=$("${sshCommand}")
exitCode="${?}"
if (( 0 != $exitCode )); then
printf "FAILED - sshCommand=[%s], exitCode=[%d], cmdOutput=[%s]\n" "${sshCommand}" "${exitCode}" "${cmdOutput}"
exit 1
fi
printf "SUCCEEDED - sshCommand=[%s] exitCode=[%d]\n" "${sshCommand}" "${exitCode}"
printf "%s\n\n" "${cmdOutput}"
} # end findInvalidArtifacts()
findInvalidArtifacts
+ findInvalidArtifacts
+ unset inbox sshCommand exitCode cmdOutput
+ VENDOR=(['FTPBASE']="/home/user" ['FTPSOURCEDIR']="/home/user/inbox/imaging" ['FRIENDLYNAME']="user" ['ENVIRONMENT']="dev")
+ local -A VENDOR
+ inbox=/home/user/inbox
+ printf -v sshCommand 'find -L %s \( ! -path %s -a ! -path '\''%s/*'\'' -a ! -path %s -a ! -path '\''%s/*'\'' \) -ls' /home/user/inbox /home/user/inbox /home/user/inbox /home/user/inbox/imaging /home/user/inbox/imaging
++ 'find -L /home/user/inbox \( ! -path /home/user/inbox -a ! -path '\''/home/user/inbox/*'\'' -a ! -path /home/user/inbox/imaging -a ! -path '\''/home/user/inbox/imaging/*'\'' \) -ls'
./try.sh: line 16: find -L /home/user/inbox \( ! -path /home/user/inbox -a ! -path '/home/user/inbox/*' -a ! -path /home/user/inbox/imaging -a ! -path '/home/user/inbox/imaging/*' \) -ls: No such file or directory
+ cmdOutput=
+ exitCode=127
+ (( 0 != 127 ))
+ printf 'FAILED - sshCommand=[%s], exitCode=[%d], cmdOutput=[%s]\n' 'find -L /home/user/inbox \( ! -path /home/user/inbox -a ! -path '\''/home/user/inbox/*'\'' -a ! -path /home/user/inbox/imaging -a ! -path '\''/home/user/inbox/imaging/*'\'' \) -ls' 127 ''
FAILED - sshCommand=[find -L /home/user/inbox \( ! -path /home/user/inbox -a ! -path '/home/user/inbox/*' -a ! -path /home/user/inbox/imaging -a ! -path '/home/user/inbox/imaging/*' \) -ls], exitCode=[127], cmdOutput=[]
+ exit 1
This is a stumper.这是一个树桩。 I cannot see where why find is complaining about 'no such file or directory'.
我看不出为什么 find 抱怨“没有这样的文件或目录”。
Appreciate the valiant effort, however the constructed command still does not return the desired results.感谢勇敢的努力,但是构建的命令仍然没有返回所需的结果。 The contents of finding all existing artifacts in /home/user/inbox are:
在 /home/user/inbox 中查找所有现有工件的内容是:
/home/user/inbox
/home/user/inbox/invalidDir2
/home/user/inbox/invalidDir2/invalidSubdir2
/home/user/inbox/invalidDir2/invalidSubdir2/invalidFile1
/home/user/inbox/invalidDir2/invalidSubdir2/invalidSubSubDir2
/home/user/inbox/invalidDir2/invalidSubdir2/invalidSubSubDir2/invalidSubSubSubDir2
/home/user/inbox/invalidDir2/invalidSubdir2/invalidSubSubDir2/invalidSubSubSubDir2/invalidSubSubSubSubDir2
/home/user/inbox/invalidDir2/invalidSubdir2/invalidSubSubDir2/invalidSubSubSubDir2/invalidSubSubSubSubDir2/invalidFile
/home/user/inbox/invalidDir2/invalidSubdir2/invalidSubSubDir2/invalidSubSubSubDir2/invalidFile
/home/user/inbox/invalidDir2/invalidSubdir2/invalidSubSubDir2/invalidFile
/home/user/inbox/imaging
/home/user/inbox/imaging/validFile
/home/user/inbox/imaging/invalidFile
/home/user/inbox/imaging/invalidImagingDir1
/home/user/inbox/imaging/invalidImagingDir1/invalidSubdir1
/home/user/inbox/imaging/invalidImagingDir1/invalidSubdir1/invalidFile1
/home/user/inbox/imaging/invalidImagingDir1/invalidSubdir1/invalidSubSubDir1
/home/user/inbox/imaging/invalidImagingDir1/invalidSubdir1/invalidSubSubDir1/invalidSubSubSubDir1
/home/user/inbox/imaging/invalidImagingDir1/invalidSubdir1/invalidSubSubDir1/invalidSubSubSubDir1/invalidFile
/home/user/inbox/imaging/invalidImagingDir1/invalidSubdir1/invalidSubSubDir1/invalidFile
/home/user/inbox/imaging/invalidImagingDir1/invalildFile
/home/user/inbox/invalidFile
/home/user/inbox/invalidDir1
/home/user/inbox/invalidDir1/invalidSubdir1
/home/user/inbox/invalidDir1/invalidSubdir1/invalidFile1
/home/user/inbox/invalidDir1/invalidSubdir1/invalidSubSubDir1
/home/user/inbox/invalidDir1/invalidSubdir1/invalidSubSubDir1/invalidSubSubSubDir1
/home/user/inbox/invalidDir1/invalidSubdir1/invalidSubSubDir1/invalidSubSubSubDir1/invalidFile
/home/user/inbox/invalidDir1/invalidSubdir1/invalidSubSubDir1/invalidFile
The result set should NOT contain anything matching the directory to search in, or any of the parameters passed to your function that constructs the command.结果集不应包含与要搜索的目录匹配的任何内容,或传递给构造命令的 function 的任何参数。 Results should NOT contain these lines -
结果不应包含这些行 -
/home/user/inbox
/home/user/inbox/imaging
/home/user/inbox/imaging/validFile
The command your function constructs looks like this -您的 function 构造的命令如下所示 -
find -L /home/user/inbox '(' '!' -path /home/user/inbox -a '!' -path '/home/user/inbox/*' -a '!' -path /home/user/inbox/imaging -a '!' -path '/home/user/inbox/imaging/*' ')' -ls
which returns nothing at all什么都不返回
I'm beginning to think that the find command is not what I need to obtain the desired results and that I'll need to do some more processing of the result set to disclude, probably awk or something.我开始认为 find 命令不是我获得所需结果所需要的,我需要对结果集进行更多处理才能排除,可能是 awk 或其他东西。
Relevant snippet:相关片段:
printf -v sshCommand "find -L %s \( ! -path %s -a ! -path '%s/*' -a ! -path %s -a ! -path '%s/*' \) -ls" [more args]
cmdOutput=$("${sshCommand}")
This is a classic pitfall of trying to shove a command into a variable and run it .这是试图将命令推入变量并运行它的典型陷阱。 The basic solution is to use a function, not a variable.
基本解决方案是使用 function,而不是变量。
The reason for your error is that Bash determines the name of the command you're trying to run by selecting the first word of the command line after completing all of its parsing steps.错误的原因是 Bash 在完成所有解析步骤后通过选择命令行的第一个单词来确定您尝试运行的命令的名称。 You want to use the command
find
with some arguments, but since you have "${sshCommand}"
in quotes, there's only one word in the entire command line so Bash thinks the command you want is called find -L /home/dir (. -path etc etc... )
.您想对一些 arguments 使用命令
find
,但是由于引号中有"${sshCommand}"
,整个命令行中只有一个词,因此 Bash 认为您想要的命令称为find -L /home/dir (. -path etc etc... )
。 I bet you don't have any executables with that name on your system.我打赌你的系统上没有任何同名的可执行文件。
A function equivalent of what you're trying to do might look like:相当于您尝试执行的操作的 function 可能如下所示:
_findCmd() {
searchDir=$1 # first arg is the directory to search from
shift
# each extra argument is a directory to exclude from the search
# we can loop over the list and build the arguments that find needs
# in an array
path_args=()
if (( $# > 0 )) ; then
path_args+=( "(" "!" "-path" "$1" )
shift
while (( $# > 0 )) ; do
path_args+=( "-a" "!" "-path" "$1" )
shift
done
path_args+=( ")" )
fi
find -L "$searchDir" "${path_args[@]}" -ls
}
cmdOutput=$( _findCmd /home/user/inbox /home/user/inbox "/home/user/inbox/*" /home/user/inbox/imaging "/home/user/inbox/imaging/*" )
A simple remark about your find
command关于
find
命令的简单说明
find -L /home/user/inbox ! -path '/home/user/inbox/*'
Excludes any path that starts with /home/user/inbox/
(leaving only one possible match which is /home/user/inbox
).排除以
/home/user/inbox/
开头的任何路径(只留下一个可能的匹配项/home/user/inbox
)。
Also, for excluding /home/user/inbox/imaging/validFile
while including /home/user/inbox/imaging/invalidFile
, using ! -path '/home/user/inbox/imaging/*'
此外,要排除
/home/user/inbox/imaging/validFile
而包括/home/user/inbox/imaging/invalidFile
,使用! -path '/home/user/inbox/imaging/*'
! -path '/home/user/inbox/imaging/*'
is wrong, for the same reason as above. ! -path '/home/user/inbox/imaging/*'
错误,原因同上。
Now, if your remote shell is also bash
, then you can avoid any quoting issues with the %q
formatter, for example:现在,如果您的远程 shell 也是
bash
,那么您可以避免%q
格式化程序的任何引用问题,例如:
#!/bin/bash
printf -v sshRemoteCommand 'find %q ! -path %q ! -path %q ! -path %q -ls' \
/home/user/inbox \
/home/user/inbox/imaging \
/home/user/inbox/imaging/validFile
sshCommand=(
ssh
-option1
-option2
user@ssh.example.com
"$sshRemoteCommand"
)
cmdOutput=$( "${sshCommand[@]}" 2>&1 ) || {
cmdExitCode=$?
printf 'FAILED - sshCommand=[%s], exitCode=[%d], cmdOutput=[%s]\n' \
"${sshCommand[*]}" \
"$cmdExitCode" \
"$cmdOutput"
exit 1
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.