bestsource

셸 스크립트의 변수에 명령을 저장하려면 어떻게 해야 합니까?

bestsource 2023. 5. 4. 20:07
반응형

셸 스크립트의 변수에 명령을 저장하려면 어떻게 해야 합니까?

나중에 사용할 명령을 변수(명령 출력이 아니라 명령 자체)에 저장하려고 합니다.

다음과 같은 간단한 스크립트가 있습니다.

command="ls";
echo "Command: $command"; #Output is: Command: ls

b=`$command`;
echo $b; #Output is: public_html REV test... (command worked successfully)

하지만 조금 더 복잡한 것을 시도하면 실패합니다.예를 들어, 제가 만든다면,

command="ls | grep -c '^'";

출력은 다음과 같습니다.

Command: ls | grep -c '^'
ls: cannot access |: No such file or directory
ls: cannot access grep: No such file or directory
ls: cannot access '^': No such file or directory

나중에 사용할 수 있도록 이러한 명령(파이프/복수 명령 포함)을 변수에 저장하려면 어떻게 해야 합니까?

평가 사용:

x="ls | wc"
eval "$x"
y=$(eval "$x")
echo "$y"

사용 안 함eval임의 코드 실행이 발생할 수 있는 주요 위험이 있습니다.

BashFAQ-50 - 변수에 명령을 넣으려고 하지만 복잡한 경우는 항상 실패합니다.

모든 로 묶어서 합니다."${arr[@]}"못 보게 하기 위해IFS단어 분할로 인해 단어를 분할됩니다.

cmdArgs=()
cmdArgs=('date' '+%H:%M:%S')

그리고 안에 있는 배열의 내용을 봅니다.declare -p에서는 각 명령 매개 변수가 별도의 인덱스로 표시된 내부 배열의 내용을 볼 수 있습니다.이러한 인수 중 하나에 공백이 포함된 경우 배열에 추가하는 동안 내부를 따옴표로 묶으면 Word-Spliting으로 인해 분할되지 않습니다.

declare -p cmdArgs
declare -a cmdArgs='([0]="date" [1]="+%H:%M:%S")'

명령을 실행합니다.

"${cmdArgs[@]}"
23:15:18

(또는) 전체적으로 a를 사용합니다.bash 명령을는함수하,

cmd() {
   date '+%H:%M:%S'
}

그리고 함수를 정의라고 부릅니다.

cmd

POSIXsh에는 배열이 없으므로 위치 매개 변수의 요소 목록을 작성하는 것이 가장 가까운 방법입니다. 여가 POSIX sh

# POSIX sh
# Usage: sendto subject address [address ...]
sendto() {
    subject=$1
    shift
    first=1
    for addr; do
        if [ "$first" = 1 ]; then set --; first=0; fi
        set -- "$@" --recipient="$addr"
    done
    if [ "$first" = 1 ]; then
        echo "usage: sendto subject address [address ...]"
        return 1
    fi
    MailTool --subject="$subject" "$@"
}

이 접근 방식은 리디렉션 없이 단순 명령만 처리할 수 있습니다.리디렉션, 파이프라인, 루프 중/중, if 문 등을 처리할 수 없습니다.

는 " 다일반사사용실중경다니우입인행또례는인른"를 실행할 때입니다.curl다중 헤더 필드 및 페이로드를 사용합니다.와 같이 를 정의하고 같인정의고호하수있다습니출할항를상수은을 호출할 수 .curl된 어레이

curlArgs=('-H' "keyheader: value" '-H' "2ndkeyheader: 2ndvalue")
curl "${curlArgs[@]}"

또 다른 예는,

payload='{}'
hostURL='http://google.com'
authToken='someToken'
authHeader='Authorization:Bearer "'"$authToken"'"'

이제 변수가 정의되었으므로 배열을 사용하여 명령 인수를 저장합니다.

curlCMD=(-X POST "$hostURL" --data "$payload" -H "Content-Type:application/json" -H "$authHeader")

그리고 이제 적절한 인용 확장을 수행합니다.

curl "${curlCMD[@]}"
var=$(echo "asdf")
echo $var
# => asdf

이 방법을 사용하면 명령이 즉시 평가되고 반환 값이 저장됩니다.

stored_date=$(date)
echo $stored_date
# => Thu Jan 15 10:57:16 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 10:57:16 EST 2015

백티크도 마찬가지입니다.

stored_date=`date`
echo $stored_date
# => Thu Jan 15 11:02:19 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 11:02:19 EST 2015

에 eval $(...)나중에 평가되지 않습니다.

stored_date=$(eval "date")
echo $stored_date
# => Thu Jan 15 11:05:30 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 11:05:30 EST 2015

eval을 사용하면 다음과 같이 사용할 때 평가됩니다.

stored_date="date" # < storing the command itself
echo $(eval "$stored_date")
# => Thu Jan 15 11:07:05 EST 2015
# (wait a few seconds)
echo $(eval "$stored_date")
# => Thu Jan 15 11:07:16 EST 2015
#                     ^^ Time changed

위의 예에서 인수를 사용하여 명령을 실행해야 하는 경우 저장 중인 문자열에 변수를 넣습니다.

stored_date="date -u"
# ...

Bash 스크립트의 경우 이는 거의 관련이 없지만 마지막으로 한 가지 참고 사항이 있습니다.요.eval사용자가 제어하는 문자열만 평가하고 신뢰할 수 없는 사용자의 문자열이나 신뢰할 수 없는 사용자 입력으로 작성된 문자열은 평가하지 않습니다.

bash의 경우 명령을 다음과 같이 저장합니다.

command="ls | grep -c '^'"

다음과 같이 명령을 실행합니다.

echo $command | bash

왜 그렇게 많은 대답들이 그것을 복잡하게 만드는지 모르겠습니다!사용하다alias[command] '실행할 문자열' 예:

alias dir='ls -l'

./dir
[pretty list of files]

다음 명령을 사용하여 이 문제에 직면했습니다.

awk '{printf "%s[%s]\n", $1, $3}' "input.txt"

이 명령을 동적으로 작성해야 합니다.

대상 파일 이름input.txt동적이며 공백을 포함할 수 있습니다.

awk안에 있는{}중괄호printf "%s[%s]\n", $1, $3동적입니다.

과제:

  1. 인용문이 많은 경우에는 광범위한 인용문 이스케이프 논리를 피합니다."내부에awk대본.
  2. 다음 시간마다 매개 변수 확장 방지$필드 변수입니다.

솔루션은 다음과 같습니다.eval지휘와 연상arrays작동하지 않습니다.때문에bash가변 확장 및 견적.

솔루션:

빌드bash동적 변수, 회피bash확장, 사용printf견본의

 # dynamic variables, values change at runtime.
 input="input file 1.txt"
 awk_script='printf "%s[%s]\n" ,$1 ,$3'

 # static command template, preventing double-quote escapes and avoid variable  expansions.
 awk_command=$(printf "awk '{%s}' \"%s\"\n" "$awk_script" "$input")
 echo "awk_command=$awk_command"

 awk_command=awk '{printf "%s[%s]\n" ,$1 ,$3}' "input file 1.txt"

변수 명령 실행 중:

bash -c "$awk_command"

효과가 있는 대안

bash << $awk_command

스크립트 언어를 지정하지 않으셨기 때문에tcl이러한 목적을 위한 도구 명령어.

그런 다음 첫 번째 줄에 적절한 쉬방을 추가합니다.

#!/usr/local/bin/tclsh

적절한 위치에서 검색할 수 있습니다.which tclsh.

tcl스크립트, 운영 체제 명령을 호출할 수 있습니다.exec.

저는 다양한 방법을 시도했습니다.

printexec() {
  printf -- "\033[1;37m$\033[0m"
  printf -- " %q" "$@"
  printf -- "\n"
  eval -- "$@"
  eval -- "$*"
  "$@"
  "$*"
}

출력:

$ printexec echo  -e "foo\n" bar
$ echo -e foo\\n bar
foon bar
foon bar
foo
 bar
bash: echo -e foo\n bar: command not found

보시다시피, 세 번째 것만,"$@"정확한 결과를 제공했습니다.

#!/bin/bash
#Note: this script works only when u use Bash. So, don't remove the first line.

TUNECOUNT=$(ifconfig |grep -c -o tune0) #Some command with "Grep".
echo $TUNECOUNT                         #This will return 0 
                                    #if you don't have tune0 interface.
                                    #Or count of installed tune0 interfaces.

우선, 이것을 위한 기능들이 있습니다.그러나 변수를 선호하는 경우 작업을 다음과 같이 수행할 수 있습니다.

$ cmd=ls

$ $cmd # works
file  file2  test

$ cmd='ls | grep file'

$ $cmd # not works
ls: cannot access '|': No such file or directory
ls: cannot access 'grep': No such file or directory
 file

$ bash -c $cmd # works
file  file2  test

$ bash -c "$cmd" # also works
file
file2

$ bash <<< $cmd
file
file2

$ bash <<< "$cmd"
file
file2

또는 임시 파일을 통해

$ tmp=$(mktemp)
$ echo "$cmd" > "$tmp"
$ chmod +x "$tmp"
$ "$tmp"
file
file2

$ rm "$tmp"

다음에 주문을 등록할 때 주의해야 합니다.X=$(Command)

이것은 여전히 실행 중입니다.불려가기도 전에.이를 확인하고 확인하려면 다음을 수행합니다.

echo test;
X=$(for ((c=0; c<=5; c++)); do
sleep 2;
done);
echo note the 5 seconds elapsed

나중에 사용해야 하는 경우에도 변수에 명령을 저장할 필요가 없습니다.그냥 정상적으로 실행하세요.만약 당신이 변수에 저장한다면, 당신은 어떤 종류의 것이 필요할 것입니다.eval명령을 내리거나 불필요한 셸 프로세스를 호출하여 "변수를 변경"할 수 있습니다.

언급URL : https://stackoverflow.com/questions/5615717/how-can-i-store-a-command-in-a-variable-in-a-shell-script

반응형