Linux Bash 스크립트에서 eval을 사용하는 방법

0
232
Linux Bash 스크립트에서 eval을 사용하는 방법
Fatmawati achmad zaenuri/Shutterstock.com

모든 Bash 명령 중에서 가난한 노인 eval 아마도 최악의 평판을 얻었을 것입니다. 정당화, 아니면 그냥 나쁜 언론? 우리는 가장 사랑받지 못하는 이 Linux 명령의 사용과 위험에 대해 논의합니다.

우리는 평가에 대해 이야기해야 합니다

부주의하게 사용하고, eval 예측할 수 없는 동작과 시스템 불안정으로 이어질 수 있습니다. 그 소리에서 우리는 아마 그것을 사용하지 말아야 할 것입니다. 그렇죠? 글쎄요.

자동차에 대해서도 비슷한 말을 할 수 있습니다. 잘못된 손에는 치명적인 무기입니다. 사람들은 ram-raid와 도주 차량에서 그들을 사용합니다. 우리 모두 자동차 사용을 중단해야 합니까? 물론 아닙니다. 그러나 그것들은 적절하게, 그리고 그것을 운전할 줄 아는 사람들에 의해 사용되어야 합니다.

Bash에서 변수로 작업하는 방법

관련된Bash에서 변수로 작업하는 방법

에 적용되는 일반적인 형용사 eval “악”이다. 그러나 모든 것은 그것이 어떻게 사용되는지에 달려 있습니다. 그만큼 eval 명령은 가치 하나 이상의 변수에서. 명령 문자열을 생성합니다. 그런 다음 해당 명령을 실행합니다. 이것은 스크립트를 실행하는 동안 명령의 내용이 동적으로 파생되는 상황에 대처해야 할 때 유용합니다.

사용하도록 스크립트를 작성할 때 문제가 발생합니다. eval 어딘가에서 받은 문자열에 밖의 스크립트. 사용자가 입력하거나 API를 통해 전송하거나 HTTPS 요청에 태그를 지정하거나 스크립트 외부의 다른 곳에서 입력할 수 있습니다.

만약 그 문자열이 eval 작업할 내용이 로컬 및 프로그래밍 방식으로 파생되지 않은 경우 문자열에 포함된 악성 명령 또는 기타 잘못된 형식의 입력이 포함될 위험이 있습니다. 분명히, 당신은 원하지 않습니다 eval 악성 명령을 실행합니다. 따라서 안전을 위해 사용하지 마십시오. eval 외부 생성 문자열 또는 사용자 입력으로.

평가의 첫 단계

그만큼 eval command는 기본 제공 Bash 셸 명령입니다. Bash가 있는 경우 eval 있을 것입니다.

eval 매개변수를 단일 문자열로 연결합니다. 연결된 요소를 분리하기 위해 단일 공백을 사용합니다. 인수를 평가한 다음 전체 문자열을 쉘에 전달하여 실행할 수 있습니다.

라는 변수를 만들어 봅시다. wordcount.

wordcount="wc -w raw-notes.md"

문자열 변수에는 “raw-notes.md”라는 파일의 단어 수를 세는 명령이 포함되어 있습니다.

우리는 사용할 수 있습니다 eval 전달하여 해당 명령을 실행하려면 변수의.

eval "$wordcount"

eval을 문자열 변수와 함께 사용하여 파일의 단어 수 계산

명령은 서브쉘이 아닌 현재 쉘에서 실행됩니다. 우리는 이것을 쉽게 보여줄 수 있습니다. “variables.txt”라는 짧은 텍스트 파일이 있습니다. 이 두 줄을 포함합니다.

first=How-To
second=Geek

우리는 사용할 것입니다 cat 이 줄을 터미널 창으로 보냅니다. 그럼 우리는 사용할 것입니다 eval 평가하다 cat 텍스트 파일 내의 지침이 실행되도록 명령을 실행합니다. 이것은 우리를 위해 변수를 설정할 것입니다.

cat variables.txt
eval "$(cat variables.txt)"
echo $first $second

현재 쉘에서 eval로 설정한 변수에 접근하기

사용하여 echo 우리가 볼 수 있는 변수의 값을 인쇄하려면 eval 명령은 서브쉘이 아닌 현재 쉘에서 실행됩니다.

서브쉘의 프로세스는 상위 쉘 환경을 변경할 수 없습니다. eval은 현재 쉘에서 실행되기 때문에 eval 시작한 쉘에서 사용할 수 있습니다. eval 명령.

사용하는 경우 참고하십시오. eval 스크립트에서 변경될 쉘 eval 스크립트를 실행한 셸이 아니라 스크립트가 실행 중인 하위 셸입니다.

관련된: Linux cat 및 tac 명령을 사용하는 방법

명령 문자열에서 변수 사용

명령 문자열에 다른 변수를 포함할 수 있습니다. 정수를 담기 위해 두 개의 변수를 설정할 것입니다.

num1=10 
num2=7

저장할 변수를 생성하겠습니다. expr 두 숫자의 합을 반환하는 명령입니다. 이는 명령에서 두 정수 변수의 값에 액세스해야 함을 의미합니다. 주변의 백틱에 유의하십시오. expr 성명.

add="`expr $num1 + $num2`"

우리는 결과를 보여주는 또 다른 명령을 만들 것입니다. expr 성명.

show="echo"

끝에 공백을 포함할 필요가 없습니다. echo 문자열 또는 시작 부분에 expr 끈. eval 그것을 처리합니다.

그리고 우리가 사용하는 전체 명령을 실행하기 위해:

eval $show $add

명령 문자열에서 변수 사용

내부 변수 값 expr 문자열은 다음과 같이 문자열로 대체됩니다. eval 실행할 셸에 전달되기 전에.

관련된: Bash에서 변수로 작업하는 방법

변수 안의 변수 접근하기

변수에 값을 할당한 다음 이름 그 변수를 다른 변수로. 사용 eval액세스할 수 있습니다 첫 번째 변수에 보관된 이름은 두 번째 변수에 저장됩니다. 한 가지 예가 이를 해결하는 데 도움이 될 것입니다.

이 스크립트를 편집기에 복사하고 “assign.sh”라는 파일로 저장합니다.

#!/bin/bash

title="How-To Geek"
webpage=title
command="echo"
eval $command ${$webpage}

우리는 그것을 실행 가능하게 만들어야 합니다. chmod 명령.

chmod +x assign.sh

chmod를 사용하여 스크립트를 실행 가능하게 만들기

이 문서에서 복사한 모든 스크립트에 대해 이 작업을 수행해야 합니다. 각각의 경우에 적절한 스크립트 이름을 사용하십시오.

스크립트를 실행할 때 변수의 텍스트를 봅니다. title 비록 eval 명령이 변수를 사용하고 있습니다. webpage.

./assign.sh

다른 변수에 저장된 이름에서 변수 값에 액세스

탈출 달러 기호 “$” 및 중괄호 “{}” eval이 이름이 저장된 변수 내부에 있는 값을 보도록 합니다. webpage 변하기 쉬운.

동적으로 생성된 변수 사용

우리는 사용할 수 있습니다 eval 변수를 동적으로 생성합니다. 이 스크립트를 “loop.sh”라고 합니다.

#!/bin/bash

total=0
label="Looping complete. Total:"

for n in {1..10}
do
  eval x$n=$n
  echo "Loop" $x$n
  ((total+=$x$n))
done

echo $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $x10

echo $label $total

라는 변수를 생성합니다. total 이는 우리가 생성한 변수 값의 합을 보유합니다. 그런 다음 이라는 문자열 변수를 생성합니다. label. 이것은 간단한 텍스트 문자열입니다.

우리는 10번 반복하고 10개의 변수를 생성할 것입니다. x1 까지 x10. 그만큼 eval 루프 본문의 문은 “x”를 제공하고 루프 카운터의 값을 취합니다. $n 변수 이름을 생성합니다. 동시에 새 변수를 루프 카운터 값으로 설정합니다. $n.

9 Linux Bash 스크립트의 for 루프 예제

관련된Linux Bash 스크립트에서 for 루프의 9가지 예

터미널 창에 새 변수를 인쇄한 다음 total 새로운 변수의 값으로 변수.

루프 외부에서 10개의 새 변수가 모두 한 줄에 다시 한 번 인쇄됩니다. 계산되거나 파생된 이름의 버전을 사용하지 않고 실제 이름으로도 변수를 참조할 수 있습니다.

마지막으로, 우리는 total 변하기 쉬운.

./loop.sh

eval을 사용하여 동적으로 변수 생성

관련된: 입문서: Bash 루프: for, while, until

배열과 함께 eval 사용하기

장기간 실행되고 일부 처리를 수행하는 스크립트가 있는 시나리오를 상상해 보십시오. 타임스탬프에서 생성된 이름으로 로그 파일에 기록합니다. 경우에 따라 새 로그 파일을 시작합니다. 스크립트가 완료되면 오류가 없으면 생성한 로그 파일을 삭제합니다.

당신은 단순히 그것을 원하지 않는다 rm *.log, 생성한 로그 파일만 삭제하기를 원합니다. 이 스크립트는 해당 기능을 시뮬레이션합니다. 이것은 “clear-logs.sh”입니다.

#!/bin/bash

declare -a logfiles

filecount=0 
rm_string="echo"

function create_logfile() {
  ((++filecount))
  filename=$(date +"%Y-%m-%d_%H-%M-%S").log
  logfiles[$filecount]=$filename
  echo $filecount "Created" ${logfiles[$filecount]}
}

# body of the script. Some processing is done here that
# periodically generates a log file. We'll simulate that
create_logfile
sleep 3
create_logfile
sleep 3
create_logfile
sleep 3
create_logfile

# are there any files to remove?
for ((file=1; file<=$filecount; file++))
do
  # remove the logfile
  eval $rm_string ${logfiles[$file]} "deleted..."
  logfiles[$file]=""
done

스크립트는 다음과 같은 배열을 선언합니다. logfiles . 이것은 스크립트에 의해 생성된 로그 파일의 이름을 보유합니다. 라는 변수를 선언합니다. filecount . 이것은 생성된 로그 파일의 수를 보유합니다.

또한 다음과 같은 문자열을 선언합니다. rm_string. 실제 스크립트에서 여기에는 다음이 포함됩니다. rm 명령이지만 우리는 echo 그래서 우리는 비파괴적인 방식으로 원리를 보여줄 수 있습니다.

함수 create_logfile() 각 로그 파일의 이름과 파일이 열리는 위치입니다. 우리는 단지 파일 이름그리고 파일 시스템에서 생성된 척합니다.

함수는 filecount 변하기 쉬운. 초기 값은 0이므로 생성한 첫 번째 파일 이름은 배열의 1번 위치에 저장됩니다. 이것은 의도적으로 수행되며 나중에 참조하십시오.

파일 이름은 다음을 사용하여 생성됩니다. date 명령 및 “.log” 확장자. 이름은 다음으로 표시된 위치의 배열에 저장됩니다. filecount. 이름이 터미널 창에 인쇄됩니다. 실제 스크립트에서는 실제 파일도 생성합니다.

Linux 절전 명령으로 Bash 스크립트를 일시 중지하는 방법

관련된Linux 절전 명령으로 Bash 스크립트를 일시 중지하는 방법

스크립트의 본문은 다음을 사용하여 시뮬레이션됩니다. sleep 명령. 첫 번째 로그 파일을 만들고 3초를 기다린 다음 다른 로그 파일을 만듭니다. 파일 이름의 타임스탬프가 서로 다르도록 간격을 두고 4개의 로그 파일을 만듭니다.

마지막으로 로그 파일을 삭제하는 루프가 있습니다. 루프 카운터 파일은 1로 설정됩니다. 다음 값을 포함하여 계산됩니다. filecount생성된 파일 수를 저장합니다.

만약에 filecount 로그 파일이 생성되지 않았기 때문에 는 여전히 0으로 설정됩니다. 루프 본문은 1이 0보다 작거나 같지 않기 때문에 실행되지 않습니다. 그렇기 때문에 filecount 변수가 선언될 때 0으로 설정되었으며 왜 증가했는지 ~ 전에 첫 번째 파일이 생성되었습니다.

루프 내부에서 우리는 다음을 사용합니다. eval 우리의 비파괴 rm_string 및 배열에서 검색된 파일의 이름. 그런 다음 배열 요소를 빈 문자열로 설정합니다.

이것은 우리가 스크립트를 실행할 때 보게 되는 것입니다.

./clear-logs.sh

배열에 이름이 저장된 파일 삭제

나쁜 것만은 아니다

중상모략 eval 확실히 용도가 있습니다. 대부분의 도구와 마찬가지로 무모하게 사용하면 위험하며 여러 면에서 위험합니다.

작동하는 문자열이 내부적으로 생성되고 사람, API 또는 HTTPS 요청과 같은 항목에서 캡처되지 않는지 확인하면 주요 함정을 피할 수 있습니다.

관련된: Linux 터미널에서 날짜와 시간을 표시하는 방법(Bash 스크립트에서 사용)