developer tip

현재 셸 내에서 명령의 출력을 실행하는 방법은 무엇입니까?

optionbox 2020. 10. 13. 07:41
반응형

현재 셸 내에서 명령의 출력을 실행하는 방법은 무엇입니까?


나는 파일에서 내용을 가져와 현재 셸 내에서 실행 하는 source(일명 .) 유틸리티를 잘 알고 있습니다.

이제 일부 텍스트를 셸 명령으로 변환 한 다음 다음과 같이 실행합니다.

$ ls | sed ... | sh

ls임의의 예일 뿐이며 원본 텍스트는 무엇이든 될 수 있습니다. sed또한 텍스트 변형의 예일뿐입니다. 흥미로운 부분은 sh입니다. 나는 내가 가진 것을 파이프 sh하고 그것을 실행합니다.

내 문제는 새 하위 셸을 시작하는 것을 의미합니다. 차라리 현재 셸 내에서 명령을 실행하고 싶습니다. source some-file텍스트 파일에 명령이 있으면 으로 할 수있는 것처럼.

더럽 기 때문에 임시 파일을 만들고 싶지 않습니다.

또는 현재 셸과 똑같은 특성으로 하위 셸을 시작하고 싶습니다.

최신 정보

좋아, 백틱을 사용하는 솔루션은 확실히 작동하지만 출력을 확인하고 변경하는 동안 종종이 작업을 수행해야하므로 결과를 최종적으로 파이프하는 방법이 있으면 훨씬 더 선호합니다.

슬픈 업데이트

아, /dev/stdin그게 너무 예쁘게 보였지만 더 복잡한 경우에는 작동하지 않았습니다.

그래서 나는 이것을 가지고 있습니다.

find . -type f -iname '*.doc' | ack -v '\.doc$' | perl -pe 's/^((.*)\.doc)$/git mv -f $1 $2.doc/i' | source /dev/stdin

모든 .doc파일의 확장자가 소문자인지 확인합니다.

그리고 우연히으로 처리 할 수 xargs있지만 요점은 아닙니다.

find . -type f -iname '*.doc' | ack -v '\.doc$' | perl -pe 's/^((.*)\.doc)$/$1 $2.doc/i' | xargs -L1 git mv

따라서 내가 전자를 실행하면 즉시 종료되고 아무 일도 일어나지 않습니다.


$ ls | sed ... | source /dev/stdin

업데이트 : 이 bash는 4.0 작품뿐만 아니라, tcsh를하고, 대시 (변경하는 경우 source.). 분명히 이것은 bash 3.2에서 버그가 있습니다. 로부터 bash는 4.0 릴리스 노트 :

`. '의 원인이되는 버그를 수정했습니다. 장치 또는 명명 된 파이프와 같은 비정규 파일에서 명령을 읽고 실행하는 데 실패합니다.


eval명령은 바로이 목적을 위해 존재한다.

eval "$( ls | sed... )"

bash 매뉴얼 에서 더 :

평가

          eval [arguments]

인수는 단일 명령으로 연결되어 읽혀지고 실행되며 종료 상태는 eval의 종료 상태로 반환됩니다. 인수가 없거나 비어있는 인수 만 있으면 반환 상태는 0입니다.


와, 이것은 오래된 질문이라는 것을 알고 있지만 최근에 똑같은 문제가 있음을 발견했습니다 (그게 내가 여기에 온 방법입니다).

어쨌든- source /dev/stdin대답이 마음에 들지 않지만 더 나은 대답을 찾은 것 같습니다. 사실 믿을 수 없을 정도로 간단합니다.

echo ls -la | xargs xargs

멋지죠? 실제로 이것은 여전히 ​​원하는 것을 수행하지 않습니다. 여러 줄이있는 경우 각 명령을 개별적으로 실행하는 대신 단일 명령으로 연결하기 때문입니다. 그래서 내가 찾은 해결책은 다음과 같습니다.

ls | ... | xargs -L 1 xargs

-L 1옵션은 명령 실행 당 최대 1 줄을 사용함을 의미합니다. 참고 : 줄이 후행 공백으로 끝나면 다음 줄과 연결됩니다! 따라서 각 줄이 공백이 아닌 것으로 끝나는 지 확인하십시오.

마지막으로 할 수 있습니다.

ls | ... | xargs -L 1 xargs -t

실행되는 명령을 확인합니다 (-t는 상세 함).

누군가가 이것을 읽기를 바랍니다!


명령의 출력을 소스가 될 수있는 임시 파일로 대체 하는 프로세스 대체를 사용해보십시오 .

source <(echo id)

나는 이것이 질문에 대한 "정답"이라고 믿습니다.

ls | sed ... | while read line; do $line; done

즉, while루프 로 파이프 할 수 있습니다 . read명령에서 명령은 하나 개의 라인을 얻어 stdin변수에 할당하고 $line. $line그런 다음 루프 내에서 실행되는 명령이됩니다. 입력에 더 이상 줄이 없을 때까지 계속됩니다.

이것은 다른 루프와 같은 일부 제어 구조에서는 여전히 작동하지 않지만이 경우에는 적합합니다.


`ls | sed ...`

나는 좀 ls | sed ... | source -더 예뻐질 것 같은 느낌이 들지만 불행히도 의미를 source이해하지 못합니다 .-stdin


귀하의 솔루션은 백틱으로 명령 대체라고 생각합니다 : http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html

섹션 3.4.5 참조


source그렇다면 왜 사용하지 않습니까?

$ ls | sed ... > out.sh ; source out.sh

bash 3.2 (macos)에서 mark4o의 솔루션을 사용하려면 다음 예제와 같이 파이프 라인 대신 here 문자열을 사용할 수 있습니다.

. /dev/stdin <<< "$(grep '^alias' ~/.profile)"

참고 URL : https://stackoverflow.com/questions/1279953/how-to-execute-the-output-of-a-command-within-the-current-shell

반응형