programing

명령이 빈 문자열을 출력하는지 테스트합니다.

bestprogram 2023. 4. 12. 23:08

명령이 빈 문자열을 출력하는지 테스트합니다.

명령어가 빈 문자열을 출력하는 경우 테스트하려면 어떻게 해야 합니까?

앞에서 이 질문에서는 디렉토리에 파일이 있는지 확인하는 방법을 물었습니다.다음 코드는 이를 달성하지만 더 나은 솔루션에 대해서는 rsp의 답변을 참조하십시오.


빈 출력

명령어는 값을 반환하지 않고 출력합니다.이 출력은 명령어 대체를 사용하여 캡처할 수 있습니다.$(ls -A)다음과 같이 Bash에서 비어 있지 않은 문자열을 테스트할 수 있습니다.

if [[ $(ls -A) ]]; then
    echo "there are files"
else
    echo "no files found"
fi

★★를 것에 :-A-a 전류심볼 전류)는때문에. 부모예: 및 ) ( ) ) 。..디렉토리 엔트리).

주의: 코멘트에서 지적한 바와 같이 명령어 치환에서는 후행의 새로운 행이 캡처되지 않습니다.따라서 명령어가 줄바꿈만 출력하는 경우 치환은 아무것도 캡처하지 않고 테스트는 false를 반환합니다.이것은 매우 드물지만 위의 예에서는 가능합니다.단, 하나의 새로운 행이 유효한 파일명이기 때문입니다.자세한 내용은 이 답변을 참조하십시오.


종료코드

완료되었는지 하려면 , 「 」를 합니다.$?마지막 명령어 종료 코드(성공의 경우 0, 실패의 경우 0 이외)가 포함됩니다.예를 들어 다음과 같습니다.

files=$(ls -A)
if [[ $? != 0 ]]; then
    echo "Command failed."
elif [[ $files ]]; then
    echo "Files found."
else
    echo "No files found."
fi

자세한 것은 이쪽.

TL;DR

if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]; then ...; fi

오리지널을 개선하기 위한 제안을 해 주신 netj님 감사합니다.
if [[ $(ls -A | wc -c) -ne 0 ]]; then ...; fi


이것은 오래된 질문이지만, 적어도 두 가지는 개선이나 설명이 필요하다고 생각합니다.

첫 번째 문제

첫 번째 문제는 여기에 제시된 대부분의 예가 전혀 작동하지 않는다는 것입니다.이들은 를 사용합니다.ls -al ★★★★★★★★★★★★★★★★★」ls -Al명령: 둘 다 빈 디렉토리에서 비어 있지 않은 문자열을 출력합니다.이러한 에서는 파일이 없는 경우에도 항상 파일이 있음을 보고합니다.

때문에 이, 신, 단, 신, 신, 신, 신, 신, 당, for, for, for, for, for, for, for, for, for, for, for, for,ls -A왜 걸 거죠? - 른른른른른 른른 른 - - - - - - - - - - - - -?-l출력 여부를 테스트하는 것만으로 충분할 때 "긴 목록 형식을 사용한다"는 뜻의 스위치입니다.

그래서 여기 있는 대부분의 답은 단순히 틀렸습니다.

두 번째 문제

두 번째 문제는 일부 답변은 정상적으로 동작하지만 (사용하지 않는 답변은)ls -al ★★★★★★★★★★★★★★★★★」ls -Alls -A신음

  1. 명령을 실행하다
  2. 전체 출력을 RAM으로 버퍼링합니다.
  3. 출력을 큰 한 줄의 문자열로 변환하다
  4. 그 문자열을 빈 문자열과 비교하다

대신 제가 제안하는 것은 다음과 같습니다.

  1. 명령을 실행하다
  2. 을 사용하다
    • 더 -.using head -c1
      (이 아이디어를 아래 코멘트에 게재해 주신 netj님 감사합니다)
  3. 그 숫자를 0과 비교하다

예를 들어 다음과 같은 경우입니다.

if [[ $(ls -A) ]]

다음을 사용합니다.

if [[ $(ls -A | wc -c) -ne 0 ]]
# or:
if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]

대신:

if [ -z "$(ls -lA)" ]

다음을 사용합니다.

if [ $(ls -lA | wc -c) -eq 0 ]
# or:
if [ $(ls -lA | head -c1 | wc -c) -eq 0 ]

기타 등등.

출력이 작은 경우에는 문제가 되지 않지만 출력이 큰 경우에는 차이가 클 수 있습니다.

$ time [ -z "$(seq 1 10000000)" ]

real    0m2.703s
user    0m2.485s
sys 0m0.347s

비교 대상:

$ time [ $(seq 1 10000000 | wc -c) -eq 0 ]

real    0m0.128s
user    0m0.081s
sys 0m0.105s

더 좋은 점은 다음과 같습니다.

$ time [ $(seq 1 10000000 | head -c1 | wc -c) -eq 0 ]

real    0m0.004s
user    0m0.000s
sys 0m0.007s

완전한 예

Will Vousden의 답변에서 업데이트된 예:

if [[ $(ls -A | wc -c) -ne 0 ]]; then
    echo "there are files"
else
    echo "no files found"
fi

netj 제안 후 다시 업데이트:

if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]; then
    echo "there are files"
else
    echo "no files found"
fi

jakeonfire 추가 업데이트:

grep일치하지 않으면 에러가 발생하고 종료됩니다.이를 이용하여 구문을 약간 단순화할 수 있습니다.

if ls -A | head -c1 | grep -E '.'; then
    echo "there are files"
fi

if ! ls -A | head -c1 | grep -E '.'; then
    echo "no files found"
fi

공백 삭제

테스트 중인 명령어가 빈 문자열로 처리하려는 일부 공백을 출력할 수 있는 경우 다음 대신 다음과 같이 하십시오.

| wc -c

다음을 사용할 수 있습니다.

| tr -d ' \n\r\t ' | wc -c

★★★★★★★★★★★★★★★★★★★★★★.head -c1:

| tr -d ' \n\r\t ' | head -c1 | wc -c

아니면 그런 비슷한 것.

요약

  1. 먼저 유효한 명령어를 사용합니다.

  2. 둘째, RAM에 불필요하게 저장하거나 대용량의 데이터를 처리하지 않도록 합니다.

답변에서는 출력이 항상 작다고 명시하지 않았기 때문에 출력이 커질 가능성도 고려해야 합니다.

if [ -z "$(ls -lA)" ]; then
  echo "no files found"
else
  echo "There are files"
fi

그러면 명령어가 실행되고 반환된 출력(문자열)의 길이가 0인지 확인합니다.다른 플래그가 있는지 '테스트' 설명서 페이지에서 확인할 수 있습니다.

체크할 인수 주위에 " " 를 사용합니다.그렇지 않으면 두 번째 인수(확인 대상)가 없기 때문에 빈 결과가 구문 오류가 발생합니다.

★★★★★★ls -la 반환하다. ★★★★★★★★★★★★★★★★★」..따라서 이 방법을 사용하면 작동하지 않습니다. 매뉴얼 페이지를 참조하십시오.또, 편리하고 간단해 보일지 모르지만, 쉽게 망가질 것이라고 생각합니다.결과에 따라 0 또는 1을 반환하는 작은 스크립트/어플리케이션을 작성하는 것이 훨씬 신뢰성이 높아집니다!

우아하고 bash 버전에 의존하지 않는 솔루션(실제로 다른 최신 쉘에서 작동해야 함)을 원하는 사용자 및 빠른 작업에 한 줄씩 사용하는 것을 좋아하는 사용자용입니다.자, 갑니다!

ls | grep . && echo 'files found' || echo 'files not found'

중 로서 주의해 ).ls -al 그냥 리고 and and and and and and and and and and and-l ★★★★★★★★★★★★★★★★★」-a에 저는 할 때 간단한 것을 합니다.ls

Bash 레퍼런스 매뉴얼

6.4 Bash 조건식

-z string
     True if the length of string is zero.

-n string
string
     True if the length of string is non-zero.

속기 버전을 사용할 수 있습니다.

if [[ $(ls -A) ]]; then
  echo "there are files"
else
  echo "no files found"
fi

했듯이 Jon Lin은ls -al출력됩니다(이 경우).. ★★★★★★★★★★★★★★★★★」..을(를) 필요로 합니다.ls -Al이이 、 디렉디디디디 하해해해 。

예를 들어 명령어의 출력을 셸 변수에 넣을 수 있습니다.

v=$(ls -Al)

오래된 네스트 불가 표기법은 다음과 같습니다.

v=`ls -Al`

저는 인 '둥지금은 둥지 표기법입니다.$()

이 변수가 비어 있지 않은지 테스트할 수 있습니다.

if [ -n "$v" ]; then
    echo there are files
else
    echo no files
fi

둘 다 돼요.if [ -n "$(ls -Al)" ]; then

,,,,,ls 에일리어스일 수 있습니다.를 사용하는 것이 좋을지도 모릅니다.$(/bin/ls -Al)ls(1) hier(7) 및 환경(7)참조해 주세요.~/.bashrc(고객님의 셸이 GNU bash일 경우 인터랙티브셸은 zsh로 정의되어 있습니다./etc/passwd- passwd(5)chsh(1)참조하십시오.

은 것 요.ls -al명령어를 사용하면 다음과 같은 결과가 나옵니다.

LS=`ls -la`

if [ -n "$LS" ]; then
  echo "there are files"
else
  echo "no files found"
fi

때로는 "뭔가"가 stdout이 아니라 테스트 어플리케이션 stderr에게 나타날 수 있습니다.따라서, 보다 보편적인 방법으로 기능하는 수정은 다음과 같습니다.

if [[ $(partprobe ${1} 2>&1 | wc -c) -ne 0 ]]; then
    echo "require fixing GPT parititioning"
else
    echo "no GPT fix necessary"
fi

다음은 극단적인 경우를 위한 솔루션입니다.

if [ `command | head -c1 | wc -c` -gt 0 ]; then ...; fi

이거면 될 거야

  • 모든 본 포탄에 대해
  • 명령어 출력이 모두 0인 경우
  • 출력 크기에 관계없이 효율적으로 실행

하지만,

  • 명령어 또는 그 서브프로세스가 출력되면 삭제됩니다.

지금까지의 답변은 모두 공백이 아닌 문자열을 종료하고 출력하는 명령어관한 것입니다.

대부분은 다음과 같은 의미로 파손되어 있습니다.

  • 새 행만 출력하는 명령어는 제대로 처리하지 않습니다.
  • 명령어가 늘바이트를 출력하는 경우(명령어 대체 사용 시) 대부분의 경우 Bash † 4.4부터 스팸 표준 오류가 발생합니다.
  • 대부분은 풀 출력 스트림을 슬립하기 때문에 명령어가 종료될 때까지 기다렸다가 응답합니다.되지 않습니다( "try" "try" "try" "try" "try").yes를 참조해 주세요.

이 모든 문제를 해결하고 다음 질문에 효율적으로 답변하기 위해

명령어가 빈 문자열을 출력하는 경우 테스트하려면 어떻게 해야 합니까?

다음을 사용할 수 있습니다.

if read -n1 -d '' < <(command_here); then
    echo "Command outputs something"
else
    echo "Command doesn't output anything"
fi

빈 문자열이 아닌 을 일정도 있습니다.read의 »-t들어 2.타임아웃의 경우: 2.5초 타임아웃:

if read -t2.5 -n1 -d '' < <(command_here); then
    echo "Command outputs something"
else
    echo "Command doesn't output anything"
fi

비고. 명령이 비어 있지 않은 문자열을 출력하는지 확인해야 할 경우 XY 문제가 있을 수 있습니다.

다음은 일부 명령어의 std-out 및 std-err을 임시 파일로 쓴 다음 해당 파일이 비어 있는지 확인하는 대체 방법입니다.이 접근방식의 장점은 양쪽 출력을 캡처하고 서브셸이나 파이프를 사용하지 않는다는 것입니다.이러한 후자의 측면은 트랩 배시 출구 처리를 방해할 수 있기 때문에 중요합니다(예: 여기서).

tmpfile=$(mktemp)
some-command  &> "$tmpfile"
if [[ $? != 0 ]]; then
    echo "Command failed"
elif [[ -s "$tmpfile" ]]; then
    echo "Command generated output"
else
    echo "Command has no output"
fi
rm -f "$tmpfile"

출력이 비어 있지 않은 경우 다른 명령어로 전달하기 위해 출력을 저장해야 할 수 있습니다.그렇다면 다음과 같은 것을 사용할 수 있습니다.

list=`grep -l "MY_DESIRED_STRING" *.log `
if [ $? -eq 0 ]
then
    /bin/rm $list
fi

하면, 「 」는rm목록이 비어 있으면 명령이 중단되지 않습니다.

질문 코멘트에서 tripleee가 언급한 바와 같이 moreutils를 사용합니다. ifne('나름'은 '나름'을 선택합니다.

, 「」가 필요합니다.ifne -n테스트를 부정합니다.

ls -A /tmp/empty | ifne -n command-to-run-if-empty-input

첫 번째 명령어의 출력이 비어 있지 않은 경우 다른 많은 응답에 비해 이 기능의 장점이 있습니다. ifne는 전체 출력을 버퍼링한 후 나중에 쓰는 것이 아니라 STDOUT에 바로 쓰기 시작합니다.이것은 초기 출력이 느리게 생성되거나 매우 길어져 셸 변수의 최대 길이를 초과하게 되는 경우에 중요합니다.

moreutils에는 거의 틀림없이 coreutils에 있어야 할 몇 가지 장점이 있습니다.껍데기 안에서 많은 시간을 보낸다면 확인해 볼 가치가 있습니다.

OP에 관심은 【OP】【OP】【OP】【OP】【OP】이다.dirempty/exists이 도구는 작성 시 아직 검토 중이며 한동안 사용되었습니다(범프가 필요할 수 있음).

언급URL : https://stackoverflow.com/questions/12137431/test-if-a-command-outputs-an-empty-string