简体   繁体   English

Bash 查找命令:没有那个文件或目录

[英]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.

相关问题 bash找不到git命令:没有这样的文件或目录 - bash can't find git command: No such file or directory bash 脚本中的 find 命令导致“没有这样的文件或目录”错误仅适用于目录? - find command in bash script resulting in “No such file or directory” error only for directories? 如何确定ls命令输出是文件还是目录Bash - How to find out if ls command output is file or a directory Bash bash - 排除“for file in $(find ...)”中的目录 - bash - excluding directory in “for file in $(find …)” Bash脚本,用于使用find命令在目录中递归搜索外部文件中定义的文件(文件类型) - Bash script for searching of files (file types) which are defined in the external file recursively in directory using find command 命令行参数bash中没有这样的文件或目录错误 - Command line argument No such file or directory error in bash 使用#!bin / bash文件更改目录和运行命令 - change directory and run command with #!bin/bash file 找不到返回的文件或目录,但是bash命令中没有提到文件或目录? - Returning file or directory not found, but no file or directory mentioned in bash command? 查找文件,将其转换并保留在bash的原始目录中 - Find file, convert it and leave in orginal directory in bash Bash在目录中的文件/文件中查找代码行 - Bash find line of code in a file/files, in directory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM