Programing

찾기에서 exec와 함께 세미콜론 (;) 대 더하기 (+) 사용

lottogame 2020. 6. 25. 08:04
반응형

찾기에서 exec와 함께 세미콜론 (;) 대 더하기 (+) 사용


사용시 출력에 차이가있는 이유

find . -exec ls '{}' \+

find . -exec ls '{}' \;

나는 얻었다 :

$ find . -exec ls  \{\} \+
./file1  ./file2

.:
file1  file2  testdir1

./testdir1:
testdir2

./testdir1/testdir2:


$ find . -exec ls  \{\} \;
file1  file2  testdir1
testdir2
./file2
./file1

이것은 예제와 함께 가장 잘 설명 될 수 있습니다. 다음 find과 같은 파일 나타납니다.

file1
file2
file3

-exec세미콜론 ( find . -exec ls '{}' \;) 과 함께 사용하면

ls file1
ls file2
ls file3

그러나 더하기 부호 ( find . -exec ls '{}' \+)를 대신 사용하면 가능한 한 많은 파일 이름이 단일 명령에 인수로 전달됩니다.

ls file1 file2 file3

파일 이름의 수는 시스템의 최대 명령 행 길이에 의해서만 제한됩니다. 명령이이 길이를 초과하면 명령이 여러 번 호출됩니다.


지금까지의 모든 대답은 정확합니다. 내가 사용하여 설명되어있는 문제의 (나에게) 명확 시위로이 제공 echo보다는 ls:

세미콜론을 사용하면 echo파일 (또는 다른 파일 시스템 객체)이 발견 될 때마다 명령 이 한 번 호출됩니다.

$ find . -name 'test*' -exec echo {} \;
./test.c
./test.cpp
./test.new
./test.php
./test.py
./test.sh

더하기 명령 echo은 한 번만 호출됩니다. 발견 된 모든 파일은 인수로 전달됩니다.

$ find . -name 'test*' -exec echo {} \+
./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh

find많은 수의 결과가 나오면 호출되는 명령이 여러 개의 인수에서 질식되는 것을 알 수 있습니다.


남자에게서

-exec 명령;

명령을 실행하십시오. 0 상태가 반환되면 true입니다. 찾을 다음의 모든 인수는 ';'로 구성된 인수까지 명령에 대한 인수로 간주됩니다. 발생합니다. 문자열 '{}'은 (는) 일부 버전의 find에서와 같이 단독 인수가 아닌 명령 인수에서 발생하는 모든 위치에서 처리되는 현재 파일 이름으로 바뀝니다. 이 두 구조는 모두 쉘에서 확장되는 것을 막기 위해 이스케이프 처리 ( '\')하거나 인용해야합니다. '-exec'옵션 사용의 예는 예 섹션을 참조하십시오. 지정된 명령은 일치하는 각 파일마다 한 번씩 실행됩니다. 명령은 시작 디렉토리에서 실행됩니다. -exec 옵션 사용과 관련하여 피할 수없는 보안 문제가 있습니다. 대신 -execdir 옵션을 사용해야합니다.

-exec 명령 {} +

This variant of the -exec option runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca- tions of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of '{}' is allowed within the command. The command is executed in the starting directory.

so the way I understand it, \; executes seperate commands and + appends each name. its basically the way it is executed, as the \ is an escape so its

ls testdir1; ls testdir2 

vs

ls testdir1 testdir2

doing the above in my shell mirrored the output your question.

UPDATE 2

So, why would you want to use +

say i have two files 1.tmp and 2.tmp

1.tmp:

1
2
3

2.tmp:

0
2
3

running

 find *.tmp -exec diff {} \;
> diff: missing operand after `1.tmp'
> diff: Try `diff --help' for more information.
> diff: missing operand after `2.tmp'
> diff: Try `diff --help' for more information.

where if you use + and concatenate the finds results like so:

find *.tmp -exec diff {} \+
1c1,3
< 1
---
> 0
> 2
> 30

so in this case its the difference between diff 1.tmp; diff 2.tmp and diff 1.tmp 2.tmp

There are cases where \; is appropriate and + will be necessary. using + with rm is one such instance, where if you are removing a large number of files speed in much improved over ;. I always like learning more about find, it is such a powerful and handy util I hope this is sufficient enough in explaining the differences.


Here's the deal: find has special syntax. You use the {} as they are because they have meaning to find as the pathname of the found file and (most) shells don't interpret them otherwise. You need the backslash \; because the semicolon has meaning to the shell, which eats it up before find can get it. So what find wants to see AFTER the shell is done, in the argument list passed to the C program, is

"-exec", "rm", "{}", ";"

but you need \; on the command line to get a semicolon through the shell to the arguments.

You can get away with \{\} because the shell-quoted interpretation of \{\} is just {}. Similarly, you could use '{}'.

What you cannot do is use

 -exec 'rm {} ;'

because the shell interprets that as one argument,

"-exec", "rm {} ;"

and "rm {} ;" isn't the name of a command. (At least unless someone is really screwing around.)

Update

the difference is between

$ ls file1
$ ls file2

and

$ ls file1 file2

The + is catenating the names ont a command line.


The difference between ; (semicolon) or + (plus sign) is how the arguments are passed into find's -exec/-execdir parameter. For example:

  • using ; will execute multiple commands (separately for each argument),

    Example:

    $ find /etc/rc* -exec echo Arg: {} ';'
    Arg: /etc/rc.common
    Arg: /etc/rc.common~previous
    Arg: /etc/rc.local
    Arg: /etc/rc.netboot
    

    All following arguments to find are taken to be arguments to the command.

    The string {} is replaced by the current file name being processed.

  • using + will execute the least possible commands (as the arguments are combined together). It's very similar to how xargs command works, so it will use as many arguments per command as possible to avoid exceeding the maximum limit of arguments per line.

    Example:

    $ find /etc/rc* -exec echo Arg: {} '+'
    Arg: /etc/rc.common /etc/rc.common~previous /etc/rc.local /etc/rc.netboot
    

    The command line is built by appending each selected file name at the end.

    Only one instance of {} is allowed within the command.

See also:


we were trying to find file for housekeeping.

find . -exec echo {} \; command ran over night in the end no result.

find . -exec echo {} \ + have results and only took a few hours.

Hope this helps.

참고URL : https://stackoverflow.com/questions/6085156/using-semicolon-vs-plus-with-exec-in-find

반응형