명령 출력을 쉘 변수에 할당하려면 어떻게해야합니까?


76

표현식의 결과를 변수에 할당하고 문자열로 연결 한 다음 에코합니다. 내가 가진 것은 다음과 같습니다.

#!/bin/bash
cd ~/Desktop;
thefile= ls -t -U | grep -m 1 "Screen Shot";
echo "Most recent screenshot is: "$thefile;

그러나 그 결과는 다음과 같습니다.

Screen Shot 2011-07-03 at 1.55.43 PM.png
Most recent screenshot is: 

따라서에 할당되지 않은 것처럼 보이며 $thefile실행되면서 인쇄되고 있습니다.


답변:


108

쉘 지정은 등호 뒤에 공백이없는 단일 단어입니다. 그래서 당신이 쓴 것은 빈 값을 할당합니다 thefile; 또한 할당은 명령과 함께 그룹화 thefile되므로 환경 변수를 만들고 할당은 해당 특정 명령에 대해 로컬입니다. 즉 ls, 지정된 값 을 보려는 호출 만 가능합니다 .

명령의 출력을 캡처하려면 명령 대체 를 사용해야합니다 .

thefile=$(ls -t -U | grep -m 1 "Screen Shot")

(일부 문헌은 대체 구문을 보여줍니다 thefile=`ls …`. 역 따옴표 내부 인용은 때때로 이상하다는 점을 제외하고는 역 따옴표 구문은 달러 괄호 구문과 같습니다 $(…).

스크립트에 대한 기타주의 사항 :

  • (시간순 -t정렬)과 -U(정렬하지 않음 )을 결합하는 것은 의미가 없습니다. 그냥 사용하십시오 -t.
  • grep스크린 샷을 일치시키는 데 사용 하는 대신 와일드 카드를 전달 하고 첫 번째 파일을 캡처하는 데 ls사용 하는 것이 더 명확 head합니다.

    thefile=$(ls -t *"Screen Shot"* | head -n 1)
  • 의 출력을 구문 분석ls 하는 것은 일반적으로 나쁜 생각입니다 . 인쇄 할 수없는 문자가 포함 된 파일 이름이있는 경우 상당히 실패 할 수 있습니다. 그러나 날짜를 기준으로 파일을 정렬하는 것은 어렵 기 ls때문에 파일 이름에 인쇄 할 수없는 문자 나 백 슬래시가없는 경우 허용되는 솔루션입니다.

  • 변수 치환에 항상 큰 따옴표를 사용 하십시오.

    echo "Most recent screenshot is: $thefile"

    큰 따옴표가 없으면 변수 값이 다시 확장되어 공백이나 다른 특수 문자가 포함되어 있으면 문제가 발생할 수 있습니다.

  • 줄 끝에 세미콜론이 필요하지 않습니다. 중복되지만 무해합니다.
  • 쉘 스크립트에서는 종종 포함하는 것이 좋습니다 set -e. 명령이 실패하면 (0이 아닌 상태를 리턴하여) 쉘이 종료되도록 지시합니다.

GNU 찾기 (특히 비 임베디드 Linux 또는 Cygwin을 실행중인 경우)가있는 경우 가장 최근 파일을 찾는 또 다른 방법이 있습니다. find파일과 날짜를 나열 하고 가장 어린 파일을 사용 sort하고 tail추출하는 것입니다.

thefile=$(find -maxdepth 1 -type f -name "*Screen Shot*" -printf "%T@ %p" |
          sort -k 1n | tail -n 1)

bash 대신 zsh에서이 스크립트를 작성하려는 경우 zsh에는 이름뿐만 아니라 파일 메타 데이터에서도 와일드 카드 일치를 허용하는 glob 한정자 가 있으므로 최신 파일을 훨씬 쉽게 포착 할 수 있습니다. (om[1])패턴 뒤 의 부분은 glob 한정자입니다. om나이가 증가함에 따라 (즉, 수정 시간에 따라 가장 최신순으로) 일치를 정렬 [1]하고 첫 번째 일치 만 추출합니다. globbing은 파일 [1]이 하나의 파일을 포함한다는 것을 의미 하더라도 globbing은 파일 목록을 반환하기 때문에 기술적으로 배열이므로 전체 일치는 괄호 안에 있어야 합니다.

#!/bin/zsh
set -e
cd ~/Desktop
thefile=(*"Screen Shot"*(om[1]))
echo "Most recent screenshot is: $thefile"

7
와! 내가 기대했던 것보다 더 많은 정보. 답변 해 주셔서 감사합니다. 나는 당신이 이것에 넣은 모든 노력에 정말로 감사합니다! 당신은 나에게 정말 정말 배울 것이 많다는 것을 보여주었습니다. 나는 bash : P에 관한 책을 사러 갔다.
Nathan G.

3
그게 내가 전화 것이 무엇 확실한 대답을! :)
alex

4

multiline / multiple command / s로 수행하려면 다음을 수행하십시오.

output=$( bash <<EOF
#multiline/multiple command/s
EOF
)

또는:

output=$(
#multiline/multiple command/s
)

예:

#!/bin/bash
output="$( bash <<EOF
echo first
echo second
echo third
EOF
)"
echo "$output"

산출:

first
second
third

이것은 좋은 대답입니다. 명령의 일부로 변수를 지정할 수있는 방법이 있습니까? 예를 들어output=$(echo $someVariable)
Zach Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.