셸에서 쓸모없는 종료 명령을 최적화 할 수 있습니까?


27

쉘이 종료로 알려진 쓸모 없는 ( 또는 부분적으로 쓸모없는 ) 명령 을 수행하도록 요청받은 경우 cat hugeregularfile.txt > /dev/null해당 명령의 실행을 건너 뛸 수 있습니까 ( 또는 더 저렴한 동등한 명령을 실행할 수touch -a hugeregularfile.txt 있습니까)?

더 일반적으로, 쉘이 C 컴파일러와 유사 합니까? 만약 외부에서 관찰 가능한 행동이 추상 기계가 그것을 평가하는 것처럼 소스 코드에서 변환을 수행 할 수 있다는 점입니까?

편집하다

의 Nota 베네는 : 원래 제기로 내 질문은 쉘이 있는지 여부를 물어 제목이 있었다 허용 되지는 여부를하거나 그들이 할 수있는 구현이 존재하는지, 이러한 최적화 작업을 수행 할 수 있습니다. 둘 다 환영하지만 이론보다는 연습에 더 관심이 있습니다.


아니요, 셸은 최신 컴파일러 만큼 똑똑 하지 않습니다 . 사실, 그것은 다소 바보입니다. 쓸모없는 코드를 최적화하지 않습니다.
devnull

12
사용자의 의도가 무엇인지 추측하는 것은 쉘이해야 할 일이 아닙니다. 사용자는 해당 명령으로 거의 모든 작업을 수행하려고 시도 할 수 있었지만 가능한 경우라도이를 최적화하는 것은 잘못된 일입니다.
Chris Down

1
파일이 장치라면 cat팅을해도 큰 차이가 있습니다. 셸은 파일이 장치임을 알 수 있지만 신뢰할 필요는 없습니다.
yo '

3
@StephaneChazelas C 컴파일러는 컴파일 된 프로그램을 최적화하기 위해 "누군가에게 권한을 요청"할 필요가 없습니다. C 표준 에는 as-if 규칙이있어 그렇게 할 수 있습니다. POSIX 표준은 최소한 하나의 쉘 ( pubs.opengroup.org/onlinepubs/009695399/utilities/… )과 수많은 다른 유틸리티 ( pubs.opengroup.org/onlinepubs/009604499/utilities/wc.html)표준화 한 것으로 보입니다 . wc예를 들어). 그러나 내가 아는 한 POSIX는 쉘 최적화에 대한 입장을 취하지 않습니다. 아니면?
Idonotexist Idonotexist

2
최적화는 기능에 영향을 미치지 않으면 서 바로 가기로 성능을 향상시킵니다. 기능이 보장되는 한 POSIX 이의 제기를 볼 수 없습니다. 그래도 제안 된 최적화는 고양이 사양을 위반 합니다 . POSIX 사양에는에 의해 수행되는 최적화 유형을 수용하기위한 특정 문구가 있습니다 ksh. 그들은 별도의 프로세스가 아니라 하위 셸 환경 에서 포크 절약 최적화를 허용합니다.
Stéphane Chazelas

답변:


26

아뇨, 그건 나쁜 생각입니다.

cat hugeregularfile.txt > /dev/nulltouch -a hugeregularfile.txt동일하지 않습니다. cat출력을로 리디렉션하더라도 전체 파일을 읽습니다 /dev/null. 전체 파일을 읽는 것이 정확히 원하는 것일 수 있습니다. 예를 들어, 나중에 읽기가 훨씬 빨라지도록 캐시하기 위해. 껍질은 당신의 의도를 알 수 없습니다.

마찬가지로 C 컴파일러는 읽은 내용을 보지 않아도 파일 읽기를 최적화하지 않습니다.


2
@ 존재하지 않음 : 모든 유용한 명령 (논쟁의 여지없이 true및을 제외 하고 false)에는 잠재적 부작용이 있으며 부작용은 거의 항상 명령을 호출하는 지점입니다. 쉘은 catHalting Problem을 해결하지 않고서 ( 예 :와 같은 외부 프로그램의 ) 부작용을 알 수 없었습니다 . 따라서 제대로 시도하지 않으며 말한 것을 의미한다고 가정합니다.
cHao

5
아니요, 셸이 일어날 모든 것을 볼 수는 없습니다. 에 대해 전혀 모른다 cat. 실제로 cat하드 드라이브 포맷에서 인터넷 다운로드에 이르기까지 모든 작업을 수행 할 수 있습니다.
scai

5
"유닉스는 사용자가 어리석은 일을하는 것을 막기 위해 고안된 것이 아니며, 그로 인해 영리한 일을하는 것도 막을 수 있습니다." – Doug Gwyn
Agi Hammerthief

7
@cHao 그리고 심지어 truefalse세트 $?.
Kyle Strand

3
@scai가 위에서 지적했듯이 실행 파일은 언어 키워드와 같지 않으며 일반적인 의미가 있지만 그 cat와 같은 동작을 보장/dev/null 하지는 않습니다 . 예상되는 동작에 대한 변경을 보장하지 않으면 서 최적화를 수행하기 위해 최적화는 셸 자체 내에서 구현 된 구문 만 포함 할 수 있으며, 실행 환경에서 발견 된 것은 아니지만 이름이 아무리 직관적이든 상관 없습니다.
andybuckley

20

아니요 /dev/null. 이름은 다른 장치 나 "일반적으로"데이터 싱크 이외의 파일에 사용될 수있는 이름 일뿐입니다.

따라서 쉘 (또는 다른 프로그램)은 이름을 기반으로 작성 중인 파일 이 데이터를 "실제로"수행 하는지 여부를 알 수 없습니다 . 셸 프로그램이 수행 할 수있는 시스템 호출이없는 AFAIK도 있습니다. 예를 들어 파일 디스크립터가 실제로 아무것도 수행하지 않는지 확인합니다.

쉘에 C 컴파일러가 소스 코드에 대한 전체 개요를 가지고 있지 않기 때문에 C 프로그램에서 코드를 최적화하는 것과의 비교는 작동하지 않습니다. /dev/nullC 컴파일러가 동적으로 링크하는 함수 호출의 코드에 대해 충분히 알고 호출하지 않는 것처럼 쉘은 예제를 최적화하는 것에 대해 충분히 알지 못합니다.


4
결과적으로 ksh93은 /dev/null때로는 특별하게 취급 합니다. /dev/null예를 들어 stdout이있는 내장 echo foo >/dev/null은 어떤 쓰기도하지 않습니다 /dev/null. 내장되지 않은 명령 (예 :)을 호출하는 경우 특별한 작업을 수행하지 않습니다 cat file >/dev/null.
Mark Plotnick

사실, cat다른 것도 될 수 있습니다. 실제로 다른 것.
오리온

3
사실 /dev/null아주 몇 가지 중 하나입니다 표준화 된 경로 와 함께, /dev/tty, /dev/console, /tmp, /dev//.
Gilles 'SO- 악의

2
@MarkPlotnick 사실 cat 이다 (당신이 넣어하지 않는 한하지 사용하도록 설정된 경우 ksh93의 내장 /opt/ast/bin전에 /bin(또는이 곳 cat에서) 볼 수 있습니다 $PATH)가. 그리고 그렇습니다. cat file > /dev/null내장 read으로 내용을 수행 하지만 / dev / null에 file쓰지 않습니다 (열리고 fstats하지만).
Stéphane Chazelas

14

실행중인 명령을 최적화하지는 못하지만 (이유는 말아야 할 이유를 알려주는 많은 훌륭한 답변을 이미 받았지만) 포크, 파이프 / 소켓 쌍, 읽기를 최적화 할 수 있습니다. 그것이 할 수있는 최적화의 종류 :

  • 대부분의 최신 쉘에서 스크립트의 마지막 명령은 일반적으로 일부 trap가 설정되어 있지 않은 한 쉘 프로세스에서 실행됩니다 . 에서 예를 들어 sh -c ls, 대부분의 sh구현 ( bash, mksh, ksh, zsh, yash,의 일부 버전 ash)를 실행하는 프로세스를 포크하지 않습니다 ls.
  • 에서 ksh93명령 대체는 파이프를 만들거나 외부 명령이 호출 될 때까지 프로세스를 포크하지 않습니다 ( $(echo foo)foo: 파이프 / 소켓 페어 또는 포크없이 확장 됨 ).
  • read일부 쉘 의 내장 ( bash, AT & T ksh)은 stdin이 검색 가능함을 감지하면 단일 바이트 읽기를 수행하지 않습니다 (이 경우 큰 읽기를 수행하고 읽을 대상의 끝까지 다시 검색 함).

이 답변이 마음에 들지만 이것이 원래의 이유인지 또는 정보가 일부 참조 (내가 조사하고자하는)에서 가져온 것인지 확실하지 않습니다.
yoniLavi

3
@yoniYalovitsky, 이것이 원래 이유 입니다. ksh93은 목표가 /와 같은 프로그래밍 언어와 동등한 것으로 간주되어 최적화 분야를 선도하는 쉘 perl입니다. ksh자세한 정보 는 문서, 코드 (행운) 및 메일 링리스트를 참조하십시오.
Stéphane Chazelas

1
@HenkLangeveld, 그렇습니다. 이러한 구현이나 strace / truss / tusc sh -c 'ps -p "$$"'를 제공 ps하지 않는지 확인할 수 있습니다 .shsh
Stéphane Chazelas

1
ksh -c 'ps; ps'bash -c 'ps; ps' 의 차이점 은 흥미 롭습니다. Ksh93은 최적화를 더욱 발전시킵니다.
Henk Langeveld

1
@HenkLangeveld는 ksh우리가 여기서 말하는 구현에 달려 있습니다. mksh처럼 동작 bash합니다. 이 동작은 주로 다음과 같은 것을 최적화하기위한 것 system("some command")입니다. 신호로 종료 된 프로세스의 종료 상태 (일부 쉘에서)에 대해서는 최적화의 부작용이 있습니다. ksh93해야하는 데 사용 버그 가 트랩을 설정 한 경우에도 최적화를 수행하고 있었던에 있습니다.
Stéphane Chazelas

7

를 볼 때 cat hugeregularfile.txt > /dev/null, 껍질은 그 행동이 쓸모 없다고 믿을 수 cat없습니다. 껍질의 일부가 아니며 이론적으로도 실제로 어떤 것도 할 수 있습니다.

예를 들어, 사용자가 실행 파일 이름을 변경 한 수 rm에를 cat, 갑자기 라인이 수행하는 외부 적으로 관찰 행동, 즉, 파일을 제거.

사용자가 cat무한 루프에 들어가는 버전을 컴파일했을 수 있으므로, 쉘은 제안한대로 '종료하는 것으로 알려져있다'고 가정 할 수 없습니다.

누군가 cat의도 한대로 작동 하는 버전을 설치했을 수도 있지만 루트킷이 적절한 권한으로 실행되는 경우 루트킷을 설치하면 추가적인 부작용이 발생합니다. 다시 한 번 셸에서 적절하게 실행해야합니다.


2
실제로, 내장형으로 만들어 mksh실제로 최적화 V=$(cat file)합니다. 따라서 쉘은 그것을 최적화 할 수 있지만 단지로 변환 하지는 않습니다 touch -a.
Steve Schnepp

1
@SteveSchnepp는 cat 이다 의 내장 mksh하지만, 시스템이 내장 리조트가있어 cat경우에 GNU와 왜 어떤 옵션을 통과 cat, mksh -c 'cat /dev/null --help'같은 결과를 얻을하지 않습니다 bash -c 'cat /dev/null --help',하지만 mksh -c 'cat --help /dev/null'당신과 같은를 주는가 bash -c 'cat --help /dev/null'로 ( mksh파싱 옵션 POSIX의 내장 고양이 GNU 고양이가 GNU 방식으로 구문 분석하는 동안).
Stéphane Chazelas

bash 및 ksh93에서는 V=$(cat file)로 최적화 될 수 있습니다 V=$(< file). 내장되어 있지 않아도 속도가 빨라집니다 cat.
Henk Langeveld
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.