"찾기"에서 모든 "권한 거부"메시지를 제외하려면 어떻게합니까?
다음에서 모든 권한 거부 메시지 를 숨겨야합니다 .
find . > files_and_folders
나는 그러한 메시지가 발생할 때 실험하고 있습니다. 발생하지 않는 모든 폴더와 파일을 수집해야합니다.
권한 수준을 files_and_folders
파일에 지정할 수 있습니까?
동시에 오류를 숨기려면 어떻게해야합니까?
참고 :
*이 답변은 유스 케이스가 보증하는 것보다 더 깊을 find 2>/dev/null
수 있으며 많은 상황에서 충분할 수 있습니다. 보호되는 사례가 대체로 가설적일 수 있음에도 불구하고 가능한 한 강력한 솔루션을 찾는 데있어 크로스 플랫폼 관점과 몇 가지 고급 쉘 기술에 대한 논의에 여전히 관심이있을 수 있습니다.
* 시스템이 현지화 된 오류 메시지 를 표시하도록 구성된 경우find
아래 호출 앞에 LC_ALL=C
( LC_ALL=C find ...
)를 붙여서 영어 메시지가보고되도록 grep -v 'Permission denied'
하여 의도 한대로 작동합니다. 변함없이, 그러나, 오류 메시지 않습니다 표시 얻을는 영어로도됩니다.
귀하의 경우 쉘이 bash
나zsh
, 거기에 합리적으로 간단하면서 강력 솔루션 사용, 단지 POSIX 호환 find
기능 ; 반면 bash
POSIX의 일부가 아닌 자체, 가장 현대적인 유닉스 플랫폼은이 솔루션이 널리 휴대하고, 그와 함께 :
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
참고 : 전체 명령이 내부 명령이 완료 grep
될 때까지 기다리지 않기 때문에 의 출력 중 일부가 완료된 후 도착할 가능성이 적습니다 . 에서는 명령 에 추가하여 이를 방지 할 수 있습니다 .find
>(...)
bash
| cat
>(...)
A (거의 사용하지 않음)입니다 출력 프로세스 대체 (이 경우 출력을 리디렉션 허용, 표준 에러의 출력 (2>
명령 내부의 표준 입력으로)>(...)
.
에 추가bash
하고zsh
,ksh
뿐만 아니라 지원을 원칙으로 하지만,에서 리디렉션을 결합하는 시도 여기서 수행되는 stderr (2> >(...)
) 는 조용히 무시되는 것으로 보입니다 (에서ksh 93u+
).grep -v 'Permission denied'
필터링 아웃 (-v
) (로부터 모든 행find
구를 포함 명령의 열려진 스트림)Permission denied
과 열려진 남은 라인 출력 (>&2
).
이 접근 방식은 다음과 같습니다.
strong : 오류 메시지
grep
에만 적용되며 (파일 경로와 오류 메시지의 조합에는 적용 되지 않아 잠재적으로 오탐으로 이어질 수 있음) 권한이 거부 된 것 이외의 오류 메시지는 stderr로 전달됩니다.부작용 없음 :
find
의 종료 코드가 보존됩니다. 발생한 파일 시스템 항목 중 하나 이상에 액세스 할 수 없으면 종료 코드 가 발생합니다 (권한이 거부 된1
오류 이외의 오류가 발생했는지 여부를 알려주지는 않지만 ).
POSIX 호환 솔루션 :
완전히 POSIX 호환 솔루션에는 제한이 있거나 추가 작업이 필요합니다.
경우 find
의 출력이 포착 될 파일 어쨌든 (또는 전부 억제), 다음에서 파이프 라인 기반 솔루션 조나단 레플러의 대답은 간단하고, 강력하고, POSIX 호환은 다음과 같습니다
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
다음 리디렉션 문제의 순서가 있습니다 2>&1
와야 첫째 .
파일에 stdout 출력을 미리 캡처 하면 파이프 라인을 통해 오류 메시지 만2>&1
보낼 수 있으며, 그러면 명확하게 작동 할 수 있습니다.grep
는 유일한 단점이다 전반적인 종료 코드가 될 것입니다 grep
명령의 하지 find
가없는 경우 :이 경우 수단에의, 아니 모든 또는 오류 만 허락-거부 오류, 종료 코드가 될 것이다 1
(신호 실패 (그렇지 않으면) 권한이 거부 된 오류 이외의 오류) 0
-이는 의도의 반대입니다.
즉, find
의 종료 코드는 존재하지 않는 경로를 전달하는 것과 같은 근본적인 실패를 넘어서는 정보를 거의 전달하지 않기 때문에 거의 사용되지 않습니다 .
그러나, 특정 경우에만 일부입력 경로에 의한 권한의 부족으로 액세스가되는 됩니다 에 반영 find
(GNU와 BSD 모두의 종료 코드 find
) : 사용 권한 - 거부 오류가 발생하면 모든 처리 된 파일의 종료 코드로 설정됩니다 1
.
다음 변형은 다음을 해결합니다.
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
이제, 종료 코드는 오류 여부를 표시 이외의 Permission denied
: 발생 1
그렇다면, 0
그렇지.
즉 : 성공 (: 종료 코드는 이제 명령의 진정한 의도를 반영하는 0
) 모든 또는 오류 경우,보고 만 있는 권한 - 거부 오류가 발생하지합니다.
이것은 find
상단의 솔루션에서와 같이의 종료 코드를 전달하는 것보다 훨씬 낫습니다 .
주석의 gniourf_gniourf 는 정교한 리디렉션을 사용하여이 솔루션의 일반화 (여전히 POSIX 호환)를 제안합니다 . 이는 파일 경로를 stdout 에 인쇄하는 기본 동작에서도 작동합니다 .
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
요약 : 사용자 정의 파일 설명 3
자는 stdout ( 1
) 및 stderr ( 2
) 를 일시적으로 교체하는 데 사용 되므로 오류 메시지 만grep
stdout 을 통해 파이프 할 수 있습니다 .
이러한 리디렉션이 없으면 데이터 (파일 경로) 와 오류 메시지가 모두 grep
stdout 을 통해 파이프되어 오류 메시지 와 이름 에라는 문구 가 포함 된 (가상) 파일grep
을 구별 할 수 없습니다 . Permission denied
Permission denied
그러나 첫 번째 솔루션에서와 같이보고 된 종료 코드는 grep
's가 아니라 find
's이지만 위와 동일한 수정 사항을 적용 할 수 있습니다.
기존 답변에 대한 참고 사항 :
에 대해 유의해야 할 몇 가지 포인트가 있습니다 마이클 Brux의 대답은 ,
find . ! -readable -prune -o -print
:GNU 가 필요합니다
find
. 특히 macOS에서는 작동하지 않습니다. 물론 GNU로 작업하기 위해 명령 만 필요한 경우find
에는 문제가되지 않습니다.일부
Permission denied
오류가 여전히 나타날 수 있습니다 . 현재 사용자에게 권한이 있지만 (실행 가능) 권한 이없는 디렉토리find ! -readable -prune
의 하위 항목에 대해 이러한 오류를보고합니다 . 그 이유는 디렉토리 자체가 있기 때문이다 이다 읽을 수, 실행되지 않으며, 내려 시도 로 이 디렉토리는 오류 메시지를 트리거합니다. 즉, 일반적인 경우는 권한이 누락되는 것입니다.r
x
-prune
r
참고 : 다음 사항은 철학 및 / 또는 특정 사용 사례의 문제이며, 사용자와 관련이 없으며 명령이 사용자의 요구에 잘 맞는다고 결정할 수 있습니다. 특히 단순히 경로 를 인쇄 하는 것이 전부인 경우에는 더욱 그렇습니다 .
- If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any
find
command, then the opposite approach of proactively preventing permission-denied errors requires introducing "noise" into thefind
command, which also introduces complexity and logical pitfalls. - 예를 들어, Michael의 답변 (이 글 현재)에서 가장 많이 찬성 된 댓글 은 다음과 같이 필터 를 포함하여 명령 을 확장 하는 방법을 보여줍니다
-name
.
find . ! -readable -prune -o -name '*.txt'
그러나 이는 후행 작업이 필요 하기 때문에 의도 한대로 작동 하지 않습니다. ( 이 답변 에서 설명을 찾을 수 있습니다 ). 이러한 미묘함은 버그를 유발할 수 있습니다.-print
- If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any
The first solution in Jonathan Leffler's answer,
find . 2>/dev/null > files_and_folders
, as he himself states, blindly silences all error messages (and the workaround is cumbersome and not fully robust, as he also explains). Pragmatically speaking, however, it is the simplest solution, as you may be content to assume that any and all errors would be permission-related.mist's answer,
sudo find . > files_and_folders
, is concise and pragmatic, but ill-advised for anything other than merely printing filenames, for security reasons: because you're running as the root user, "you risk having your whole system being messed up by a bug in find or a malicious version, or an incorrect invocation which writes something unexpectedly, which could not happen if you ran this with normal privileges" (from a comment on mist's answer by tripleee).The 2nd solution in viraptor's answer,
find . 2>&1 | grep -v 'Permission denied' > some_file
runs the risk of false positives (due to sending a mix of stdout and stderr through the pipeline), and, potentially, instead of reporting non-permission-denied errors via stderr, captures them alongside the output paths in the output file.
Use:
find . 2>/dev/null > files_and_folders
This hides not just the Permission denied
errors, of course, but all error messages.
If you really want to keep other possible errors, such as too many hops on a symlink, but not the permission denied ones, then you'd probably have to take a flying guess that you don't have many files called 'permission denied' and try:
find . 2>&1 | grep -v 'Permission denied' > files_and_folders
If you strictly want to filter just standard error, you can use the more elaborate construction:
find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2
The I/O redirection on the find
command is: 2>&1 > files_and_folders |
. The pipe redirects standard output to the grep
command and is applied first. The 2>&1
sends standard error to the same place as standard output (the pipe). The > files_and_folders
sends standard output (but not standard error) to a file. The net result is that messages written to standard error are sent down the pipe and the regular output of find
is written to the file. The grep
filters the standard output (you can decide how selective you want it to be, and may have to change the spelling depending on locale and O/S) and the final >&2
means that the surviving error messages (written to standard output) go to standard error once more. The final redirection could be regarded as optional at the terminal, but would be a very good idea to use it in a script so that error messages appear on standard error.
There are endless variations on this theme, depending on what you want to do. This will work on any variant of Unix with any Bourne shell derivative (Bash, Korn, …) and any POSIX-compliant version of find
.
If you wish to adapt to the specific version of find
you have on your system, there may be alternative options available. GNU find
in particular has a myriad options not available in other versions — see the currently accepted answer for one such set of options.
Use:
find . ! -readable -prune -o -print
or more generally
find <paths> ! -readable -prune -o <other conditions like -name> -print
- to avoid "Permission denied"
- AND do NOT suppress (other) error messages
- AND get exit status 0 ("all files are processed successfully")
Works with: find (GNU findutils) 4.4.2. Background:
- The
-readable
test matches readable files. The!
operator returns true, when test is false. And! -readable
matches not readable directories (&files). - The
-prune
action does not descend into directory. ! -readable -prune
can be translated to: if directory is not readable, do not descend into it.- The
-readable
test takes into account access control lists and other permissions artefacts which the-perm
test ignores.
See also find
(1) manpage for many more details.
If you want to start search from root "/" , you will probably see output somethings like:
find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied
It's because of permission. To solve this:
You can use sudo command:
sudo find /. -name 'toBeSearched.file'
. it asks super user's password, when enter the password you will see result what you really want.You can use redirect the Standard Error Output from (Generally Display/Screen) to some file and avoid seeing the error messages on the screen! redirect to a special file /dev/null :
find /. -name 'toBeSearched.file' 2>/dev/null
You can use redirect the Standard Error Output from (Generally Display/Screen) to Standard output (Generally Display/Screen), then pipe with grep command with -v "invert" parameter to not to see the output lines which has 'Permission denied' word pairs:
find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'
I had to use:
find / -name expect 2>/dev/null
specifying the name of what I wanted to find and then telling it to redirect all errors to /dev/null
expect being the location of the expect program I was searching for.
Pipe stderr
to /dev/null
by using 2>/dev/null
find . -name '...' 2>/dev/null
You can also use the -perm
and -prune
predicates to avoid descending into unreadable directories (see also How do I remove "permission denied" printout statements from the find program? - Unix & Linux Stack Exchange):
find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders
Redirect standard error. For instance, if you're using bash on a unix machine, you can redirect standard error to /dev/null like this:
find . 2>/dev/null >files_and_folders
While above approaches do not address the case for Mac OS X because Mac Os X does not support -readable
switch this is how you can avoid 'Permission denied' errors in your output. This might help someone.
find / -type f -name "your_pattern" 2>/dev/null
.
If you're using some other command with find
, for example, to find the size of files of certain pattern in a directory 2>/dev/null
would still work as shown below.
find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$
.
This will return the total size of the files of a given pattern. Note the 2>/dev/null
at the end of find command.
Those errors are printed out to the standard error output (fd 2). To filter them out, simply redirect all errors to /dev/null:
find . 2>/dev/null > some_file
or first join stderr and stdout and then grep out those specific errors:
find . 2>&1 | grep -v 'Permission denied' > some_file
Simple answer:
find . > files_and_folders 2>&-
2>&-
closes (-
) the standard error file descriptor (2
) so all error messages are silenced.
- Exit code will still be
1
if any 'Permission denied
' errors would otherwise be printed
Robust answer for GNU find
:
find . -type d \! \( -readable -executable \) -prune -print -o -print > files_and_folders
Pass extra options to find
that -prune
(prevent descending into) but still -print
any directory (-type
d
) that does not (\!
) have both -readable
and -executable
permissions, or (-o
) -print
any other file.
-readable
and-executable
options are GNU extensions, not part of the POSIX standard- May still return '
Permission denied
' on abnormal/corrupt files (e.g., see bug report affecting container-mounted filesystems usinglxcfs
< v2.0.5)
Robust answer that works with any POSIX-compatible find
(GNU, OSX/BSD, etc)
{ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v 'Permission denied'; [ $? = 1 ]; } 3>&2 2>&1
Use a pipeline to pass the standard error stream to grep
, removing all lines containing the 'Permission denied'
string.
LC_ALL=C
sets the POSIX locale using an environment variable, 3>&2 2>&1 1>&3
and 3>&2 2>&1
duplicate file descriptors to pipe the standard-error stream to grep
, and [ $? = 1 ]
uses []
to invert the error code returned by grep
to approximate the original behavior of find
.
- Will also filter any
'Permission denied'
errors due to output redirection (e.g., if thefiles_and_folders
file itself is not writable)
To avoid just the permission denied warnings, tell find to ignore the unreadable files by pruning them from the search. Add an expression as an OR to your find, such as
find / \! -readable -prune -o -name '*.jbd' -ls
This mostly says to (match an unreadable file and prune it from the list) OR (match a name like *.jbd and display it [with ls]). (Remember that by default the expressions are AND'd together unless you use -or.) You need the -ls in the second expression or else find may add a default action to show either match, which will also show you all the unreadable files.
But if you're looking for real files on your system, there is usually no reason to look in /dev, which has many many files, so you should add an expression that excludes that directory, like:
find / -mount \! -readable -prune -o -path /dev -prune -o -name '*.jbd' -ls
So (match unreadable file and prune from list) OR (match path /dev and prune from list) OR (match file like *.jbd and display it).
use
sudo find / -name file.txt
It's stupid (because you elevate the search) and nonsecure, but far shorter to write.
None of the above answers worked for me. Whatever I find on Internet focuses on: hide errors. None properly handles the process return-code / exit-code. I use command find within bash scripts to locate some directories and then inspect their content. I evaluate command find success using the exit-code: a value zero works, otherwise fails.
The answer provided above by Michael Brux works sometimes. But I have one scenario in which it fails! I discovered the problem and fixed it myself. I need to prune files when:
it is a directory AND has no read access AND/OR has no execute access
See the key issue here is: AND/OR. One good suggested condition sequence I read is:
-type d ! -readable ! -executable -prune
This does not work always. This means a prune is triggered when a match is:
it is directory AND no read access AND no execute access
This sequence of expressions fails when read access is granted but no execute access is.
After some testing I realized about that and changed my shell script solution to:
nice find /home*/ -maxdepth 5 -follow \
\( -type d -a ! \( -readable -a -executable \) \) -prune \
-o \
\( -type d -a -readable -a -executable -a -name "${m_find_name}" \) -print
The key here is to place the "not true" for a combined expression:
has read access AND has execute access
Otherwise it has not full access, which means: prune it. This proved to work for me in one scenario which previous suggested solutions failed.
I provide below technical details for questions in the comments section. I apologize if details are excessive.
- ¿Why using command nice? I got the idea here. Initially I thought it would be nice to reduce process priority when looking an entire filesystem. I realized it makes no sense to me, as my script is limited to few directories. I reduced -maxdepth to 3.
- ¿Why search within /home*/? This it not relevant for this thread. I install all applications by hand via source code compile with non privileged users (not root). They are installed within "/home". I can have multiple binaries and versions living together. I need to locate all directories, inspect and backup in a master-slave fashion. I can have more than one "/home" (several disks running within a dedicated server).
- ¿Why using -follow? Users might create symbolic links to directories. It's usefulness depends, I need to keep record of the absolute paths found.
You can use the grep -v invert-match
-v, --invert-match select non-matching lines
like this:
find . > files_and_folders
cat files_and_folders | grep -v "permission denied" > files_and_folders
Should to the magic
-=For MacOS=-
Make a new command using alias: just add in ~/.bash_profile line:
alias search='find / -name $file 2>/dev/null'
and in new Terminal window you can call it:
$ file=<filename or mask>; search
for example:
$ file=etc; search
If you are using CSH or TCSH, here is a solution:
( find . > files_and_folders ) >& /dev/null
If you want output to the terminal:
( find . > /dev/tty ) >& /dev/null
However, as the "csh-whynot" FAQ describes, you should not use CSH.
You also an easy solution to put your find results in a file.
find . -name 'NameOfSearchedFile' >> results.txt
'programing' 카테고리의 다른 글
이진 세마포어와 뮤텍스의 차이점 (0) | 2020.09.29 |
---|---|
JavaScript에서 문자열이 같은지 확인하는 올바른 방법은 무엇입니까? (0) | 2020.09.29 |
GIT에서 사용자 이름과 비밀번호를 저장하는 방법은 무엇입니까? (0) | 2020.09.29 |
C #에서 문자열을 열거 형으로 변환 (0) | 2020.09.29 |
목록 이해력 대 람다 + 필터 (0) | 2020.09.29 |