한 줄에 명령이 저장된 file.txt가 있고(이 명령은 콘솔에서 실행할 때 유효함) sh와 같이 한 줄에서 실행하고 싶습니다.
cat file.txt | eval
없어진 물건 있어요? 어떤 팁이 있나요?
그리고 많은 명령(한 줄에 하나씩)이 포함된 파일이 있고 단 하나의 명령(전체 한 줄)만 실행하고 싶다면 어떻게 해야 합니까? 내 첫 번째 아이디어는 다음과 같습니다.
head -n5 | tail -n1 | eval
답변1
eval
stdin에서 명령 문자열을 읽지 않습니다.
eval "$(cat file.txt)"
# or easier, in ksh/bash/zsh
eval "$(<file.txt)"
# usually you cannot be sure that a command ends at the end of line 5
eval "$(head -n 5 file.txt)"
대신 명령이 파일에 있는 경우 표준 또는 / /를 eval
사용할 수 있습니다 ..
bash
zsh
ksh
source
source ./file
( 을 추가하는 것이 중요합니다 ./
. 그렇지 않으면 현재 디렉토리에서 를 고려하기 전에 in 을 source
찾습니다 . POSIX 모드에서는 에서 찾을 수 없더라도 현재 디렉토리에서 을 고려하지 않습니다 .)file
$PATH
file
bash
file
$PATH
물론 파일의 일부를 선택할 때는 작동하지 않습니다. 이는 다음을 통해 수행할 수 있습니다.
head -n 5 file.txt >commands.tmp
source ./commands.tmp
또는 (ksh93, zsh, bash 사용):
source <(head -n 5 file.txt)
답변2
따라서... 귀하의 질문에 대한 해결책은 100% 가능하며 (의 맥락에서 make
) 중요합니다.
나는 makefile을 사용하여 이 문제를 겪었고, 이미 $(...)
변수를 호출하는 데 사용하는 makefile에 bash 명령을 중첩하는 것이 어렵다는 점을 감안할 때, 당신이 요구하는 것을 정확하게 수행할 수 있다는 것은 좋은 일입니다.
를 사용하는 대신 또는 의 시스템 명령을 eval
사용하세요 .awk
perl
// command_list.sh:
echo "1"
echo "2"
echo "3"
// command line prompt:
$: cat command_list.sh | awk '{system($0)}'
1
2
3
그리고 명령 구축은 다음과 같습니다.
// a readable version--rather than building up an awk miniprogram,
// split into logical blocks:
$: cat inputs.txt | awk '{print "building "$1" command "$2" here "}' | awk '{system($0)}'
답변3
파이프라인의 각 명령은 별도의 프로세스로 실행되므로 파이프에서 읽으려는 경우 현재 환경 내에서 무언가를 평가하는 것은 기술적으로 불가능합니다.
그러나 달성하려는 작업에 따라 중요하지 않을 수도 있습니다. 어쨌든 다음은 eval
파이프의 내용에 대해 실행됩니다.
❯ echo echo hi | eval "$(cat -)"
hi
다음은 캐치의 예입니다. 다음과 같은 내용은 인쇄되지 않습니다 1
.
❯ echo a=1 | eval "$(cat -)"; echo $a
대신 다음을 수행해야 합니다.
❯ echo a=1 | { eval "$(cat -)"; echo $a; }
1
답변4
을 사용하기로 결정하지 않은 경우 eval
다음을 사용하십시오 sh
.
cat file.txt | sh
예, 별도의 sh 인스턴스에서 실행되지만 해당 사실은 자체 문서화됩니다.
그리고 다음도 있습니다 while read
:
cat file.txt | while read cmd; do eval $cmd; done
file.txt의 다섯 번째 줄에서 명령을 실행하려면:
sed -n 5p file.txt | sh
(나는 이것이 오래된 질문이라는 것을 알고 있습니다.)