배쉬 : 평가 및 에코 사용


2

이것은 정말 구체적인 질문입니다. 나는 그것의 외모로 효율성의 이름에서 필요보다 더 복잡했을 수도있는 스크립트를 만들었습니다. 정말 효율적입니까? 몰라요 그것을 쓰는 올바른 방법입니까? 몰라요

그래서이 질문을하는 이유는 아래 코드를 작성하는 방법을 향상시킬 수 있는지 알고 싶습니다. 그것이 분명하지 않으면 나는 강타하는 초보자이지만 스크립트는 그 목적을 완성합니다.

이 코드는 변수를 정의하려고 s$counter= s1, s2, s3, s4...이전에 정의 된 변수의 측면에서 s1$js2$j함께 j목록 (이전에 정의)의 아이템 인 문자열.

counter=1 
for j in ${list[@]}
    do
            eval s$counter=$(eval "echo \$s1$j")
            eval s$((counter+1))=$(eval "echo \$s2$j")
            counter=$((counter+2))
    done

혼란 스럽지만 나와는 맨손이었습니다. 내부 eval$(eval "echo \$s1$j")es의 값을 반환한다는 의미입니다 s1$j. 두 번째 eval는 eval s$counter =...은 변수를 정의하는 것을 의미합니다.s1, s2, s3, s4 ...

그래서 예는 다음과 같습니다의 첫 번째 FOOR 루프 말할 수 있도록 j=a다음 $(eval "echo \$s1$j") == $s1a의 값으로, s1a 예를 들어는 "하자, 이전의 스크립트에서 정의 된 s1a=10"그래서 두 번째 경우에, eval우리는 내용의 명령을 평가한다 " s1=10".

그것은 작동하지만, 이것이 가능한 메모리 위협이나 그와 비슷한 무언가를 일으킬 수 있습니까?

이 코드 줄과 동일한 아이디어입니다.

eval $(echo "sed -i '$(eval echo '17i$sed17line')' $file")

어디는 sed17line내가의 라인 (17)에 추가 할 것입니다 file. 그것은 내가 변수로 사용하고 따라서 나는의 조합을 사용하고 왜 이유에 대한 스크립트를 사용하려는 작업에 따라 달라집니다 echoeval.

다시, 나는 그 결과가 내가 원했던 것이 될 때까지 그 의미에 대해 생각할 수있는 모든 것을 시도했다.

나는 모든 것이 올바른지 확인하고 정보를 찾아야하는 곳에서 개선 할 수있는 방법이 있는지 확인하고 싶습니다. 감사!


Bash에는 tldp.org/LDP/Bash-Beginners-Guide/html/sect_10_02.html 배열 구성 이 있습니다. 그러나 일반적으로 간단한 목록 처리 만 있으면됩니다. 또한 한 줄에 하나의 평가로 충분합니다. Eval은 확장 문자열을 마치 스크립트에있는 것처럼 취급합니다.
T Nierath

당신이 맞아요! 하나의 평가 만 필요합니다. 감사!
MO

답변:


1

eval( this and this ) 및 echo( here )에 문제가 있음을 잘 알고 있습니다 . 당신은 피해야합니다 eval, 오용하기 쉽습니다.

이러한 명령이 특정 경우에 완전히 안전하더라도 여기서 삭제하는 것이 eval좋습니다. 코드가 실제로 너무 복잡합니다.


첫 번째 예제는 배열로 훨씬 깨끗해집니다. 이것은 내 데비안의 GNU bash 4.4.12에서 작동합니다.

# preparing variables
unset -v list s s1 s2
declare -a list=( foo 'X Y' bar baz )
declare -a s
declare -A s1=( [foo]='FOO 1' [bar]='BAR 2' [baz]='BAZ beep; eject /dev/sr0' )
declare -A s2=( [foo]='oof oof' [bar]='rab rab' [baz]='zab zab' [X Y]='9')

# your code rewritten, we don't even need a counter
for j in "${list[@]}"
  do
    s+=( "${s1[$j]}" "${s2[$j]}" )
  done

# checking contents of s
printf '%s\n' "${s[@]}"

힌트 : "인덱싱 된 배열", "연관 배열"및 사용법을 조사하십시오 bash.

공백 ( X Y)이 있는 요소 는 나에게 특별한 것이 아닙니다. 하지만 코드가 깨질 것입니다. 나는 또한 할 수 있습니다 BAZ beep; eject /dev/sr0내에서 s1; 난 당신이 설정 감히 s1baz='BAZ beep; eject /dev/sr0',이 baz당신의 list배열, 코드를 실행하고 어떻게되는지. 이것이 eval가능한 것입니다. 이제 내가 rm -rf ~/대신 넣었다고 상상해보십시오 eject ….


두 번째 예는 다음과 같이 크게 단순화 될 수 있습니다.

sed -i "17i$sed17line" "$file"

필요 없을 때 두 번 사용하는 장치를 만들었으므로 eval+에 대한 편견이있는 것 같습니다 echo. 아마도 이것이 필요할 때 변수가 항상 값으로 확장되지는 않기 때문일 수 있습니다. 그렇다면의 '작은 따옴표와 큰 따옴표 ( ") 의 차이점을 조사하십시오 bash.

의심을 품고 질문을 해준 것에 대한 찬사.


감사! 처리해야 할 정보가 너무 많았 기 때문에 모든 정보를 얻으려고 조심할 것입니다. 나는 편견이 있다고 말하지 않고 지식이 부족하다고 말하고 싶습니다. 나는이 같은 포럼에있는 모든 대답을하려고 무슨 특별히 인터넷 검색을 할 때 사용하는 것이었다 eval하고 echo. 그것은 내가 코드의 단계가 나를 그 대답으로 인도하는 것이라고 생각하는 방식 일 수도 있지만 그럼에도 불구하고 그들은 효과가 있었고 나에게 의미가있었습니다. 이제 코드를 개선하려고합니다.
MO

이 코드는 매우 구체적으로 사용되므로의 잘못된 사용법에 대해 걱정하지 않아도 eval됩니다. 평가가 휴대용이라고 하시겠습니까? 그래도 당신이 제안한 방식을 이해하기 위해 최선을 다하겠습니다.
MO

순진하게 사용자 입력을 사용하고 나중에 더 큰 문자열의 일부인 경우에도 입력을 실행하면 모든 코드를 실행하는 데 악용 될 수 있습니다. 그러나 스크립트가 루트 권한으로 실행되지 않는 한 이것은 중요하지 않습니다. 또한 var=$(<prog>)prog를 하위 프로세스로 실행하고 출력을 변수에 할당 하는 공통 패턴이 사용 됩니다. eval이 경우에는 필요 하지 않습니다 .
T Nierath
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.