[bash] 명령이 빈 문자열을 출력하는지 테스트

명령이 빈 문자열을 출력하는지 어떻게 테스트 할 수 있습니까?



답변

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


빈 출력

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

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

심볼릭 현재 ( ) 및 부모 ( ) 디렉토리 항목 이 생략되어 있기 때문에 내가 -A아닌 사용 -a했습니다 ....

참고 : 주석에서 지적했듯이 명령 대체 는 후행 줄 바꿈을 캡처하지 않습니다 . 따라서 명령이 개행 출력 하면 대체는 아무것도 캡처하지 않고 테스트는 false를 리턴합니다. 아주 드물지만 위의 예에서는 단일 줄 바꿈이 유효한 파일 이름이므로 가능합니다! 이 답변에 대한 자세한 정보 .


종료 코드

명령이 성공적으로 완료되었는지 확인 $?하려면 마지막 명령의 종료 코드 (성공의 경우 0, 실패의 경우 0이 아님)를 포함하는 inspect를 검사 할 수 있습니다 . 예를 들면 다음과 같습니다.

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 -alls -Al명령을 사용합니다 . 이러한 예제 는 파일 이없는 경우에도 항상 파일이 있다고보고합니다 .

이러한 이유로 당신은 그냥 사용해야합니다 ls -A-왜 -l출력이 있는지 여부에 관계없이 원하는 것이 테스트 될 때 누군가가 “긴 목록 형식 사용”을 의미 하는 스위치를 사용하고 싶습니까?

따라서 대부분의 대답은 간단하지 않습니다.

두 번째 문제

두 번째 문제는 동안이다 일부 답변이 잘 작동 (사람들을 그 않는 사용 ls -al또는 ls -Al하지만 ls -A그들은 모두 같은 것을 할 대신) :

  1. 명령을 실행
  2. 전체 출력을 RAM에 버퍼링
  3. 출력을 거대한 단일 행 문자열로 변환
  4. 해당 문자열을 빈 문자열과 비교

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

  1. 명령을 실행
  2. 저장하지 않고 출력에서 ​​문자를 계산
    • 또는 더 나은-최대 1 자의 수를 세십시오 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인지 확인합니다. 다른 플래그에 대해서는 ‘test’매뉴얼 페이지 를 확인하십시오 .

검사중인 인수 주위에 “”를 사용하십시오. 그렇지 않으면 빈 검사 결과에 두 번째 인수 (확인)가 없으므로 구문 오류가 발생합니다!

참고 : 것을 ls -la항상 반환 .하고 ..그래서하지 않습니다 작업을 사용하여이 참조 LS에게 매뉴얼 페이지를 . 또한 이것이 편리하고 쉬운 것처럼 보이지만 쉽게 깨질 것이라고 생각합니다. 결과에 따라 0 또는 1을 반환하는 작은 스크립트 / 응용 프로그램을 작성하는 것이 훨씬 더 안정적입니다!


답변

우아하고 bash 버전 독립적 인 솔루션을 원하거나 (현대 다른 쉘에서 작동해야 함) 빠른 작업을 위해 하나의 라이너를 사용하는 것을 좋아하는 사람들을 위해. 우리는 간다!

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

(주 코멘트 중 하나를 언급 한 바와 같이, ls -al사실, 단지 -l-a모든 반환 뭔가, 그래서 내 대답에 나는 간단한을 사용합니다ls


답변

배쉬 참조 매뉴얼

6.4 배쉬 조건식

-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항상 (for ...)을 출력 합니다. 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 -al명령 의 출력을 원한다고 추측한다 . 그래서 bash에서는 다음과 같은 것을 가질 것이다.

LS=`ls -la`

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