Unix 쉘 "stdin/stdout API"는 얼마나 안정적입니까?

Unix 쉘 "stdin/stdout API"는 얼마나 안정적입니까?

grepping, awking, sedding 및 piping은 모든 Unix 계열 운영 체제 사용자의 일상적인 루틴입니다. 명령줄에 있을 수도 있고 쉘 스크립트(총칭하여 이라고 함)에 있을 수도 있습니다.필터지금부터).

본질적으로 "표준" Unix CLI 프로그램 및 쉘 내장 기능(통칭하여명령이제부터) 필터가 올바르게 작동하려면 각 필터 단계에서 stdin, stdout 및 stderr에 대해 정확한 예상 형식이 필요합니다. 나는 다음에서 일부 명령의 정확한 예상 형식을 이 명령의 API라고 부릅니다.

나는 웹 개발 경험이 있는 사람으로서 이러한 종류의 데이터 수집 및 데이터 처리를 기술적으로 비교합니다.웹 스크래핑- 데이터 표현에 약간의 변화가 있을 때마다 매우 불안정한 기술입니다.

내 질문은 이제 Unix 명령 API의 안정성과 관련됩니다.

  1. Unix 계열 운영 체제의 명령은 입력 및 출력과 관련하여 공식적인 표준화를 준수합니까?
  2. 역사상 일부 중요한 명령에 대한 업데이트로 인해 해당 명령의 이전 버전을 사용하여 구축된 일부 필터의 기능이 중단된 사례가 있었습니까?
  3. Unix 명령은 시간이 지남에 따라 성숙해져서 일부 필터가 깨질 수 있는 방식으로 변경하는 것이 절대 불가능합니까?
  4. 명령 API 변경으로 인해 필터가 때때로 중단될 수 있는 경우 개발자로서 이 문제로부터 필터를 어떻게 보호할 수 있습니까?

답변1

POSIX 2008 표준에는 설명하는 섹션이 있습니다."셸 및 유틸리티". 일반적으로 스크립트가 더 이상 사용되지 않는 경우를 제외하고는 상당히 미래 지향적이어야 하지만 이러한 일이 하룻밤 사이에 발생하는 경우는 거의 없으므로 스크립트를 업데이트할 충분한 시간이 있어야 합니다.

단일 유틸리티의 출력 형식이 플랫폼과 버전에 따라 크게 달라지는 경우 POSIX 표준에는 일반적으로 보장되고 예측 가능한 출력 형식을 지정하는 -p또는 호출되는 옵션이 포함될 수 있습니다. -P이에 대한 예는 다음과 같습니다.time공익사업, 이는 매우 다양한 구현을 가지고 있습니다. 안정적인 API/출력 형식이 필요한 경우 time -p.

POSIX 표준에서 다루지 않는 필터 유틸리티를 사용해야 하는 경우 웹 스크래핑을 수행할 때 원격 웹 개발자의 손에 달려 있는 것처럼 배포 패키저/업스트림 개발자의 손에 달려 있습니다.

답변2

나는 내 경험을 바탕으로 대답하려고 노력할 것입니다.

  1. 명령은 실제로 공식적인 사양을 따르지는 않지만 줄 기반 텍스트를 사용하고 생성하기 위한 요구 사항을 준수합니다.

  2. 물론이죠. GNU 유틸리티가 사실상의 표준이 되기 전에는 많은 공급업체가 특히 psls. 이로 인해 많은 고통이 발생했습니다. 오늘날 HP만이 매우 기발한 명령을 제공합니다. 역사적으로 BSD(Berkeley Software Distribution) 유틸리티는 과거와 크게 달라졌습니다. POSIX 사양은 과거와는 단절되었지만 이제는 널리 받아들여지고 있습니다.

  3. Unix 명령은 실제로 시간이 지남에 따라 성숙해졌습니다. 이전 버전용으로 작성된 일부 스크립트를 깨는 것은 여전히 ​​불가능하지 않습니다. UTF-8을 텍스트 파일 인코딩으로 사용하는 최근 추세를 생각해 보세요. 이 변경으로 인해 tr. 과거에는 간단한 텍스트가 거의 항상 ASCII(또는 이와 유사한 것)였으므로 대문자와 소문자는 숫자 범위를 형성했습니다. UTF-8에서는 더 이상 그렇지 않습니다. 따라서 tr"대문자" 또는 "영숫자"와 같은 항목을 지정하는 다양한 명령줄 옵션을 허용하게 됩니다.

  4. 필터를 "견고하게 만드는" 가장 좋은 방법 중 하나는 특정 텍스트 레이아웃에 의존하지 않는 것입니다. 예를 들어, cut -c10-24행의 위치에 따라 달라지는 do 하지 마십시오 . cut -f2대신 탭으로 구분된 두 번째 필드를 잘라내는 방법을 사용하세요 . awk입력 줄을 $1, $2, $3...으로 나누며 기본적으로 공백으로 구분됩니다. 열 위치와 같은 하위 수준 개념보다는 "필드"와 같은 상위 수준 개념에 의존합니다. 또한 정규식을 사용하세요. sedawk가지 모두 입력의 변화에 ​​상관하지 않는 정규식으로 작업을 수행할 수 있습니다. 또 다른 비결은 필터가 까다로울 수 있는 형식으로 입력을 처리하는 것입니다. tr -cs '[a-zA-z0-9]' '[\n]'구두점 없이 텍스트를 한 줄에 한 단어로 나누는 데 사용됩니다 . 이 경우 입력 텍스트가 어떤 것인지는 신경 쓰지 않아도 됩니다.

답변3

먼저 귀하의 질문에 대한 매우 간단한 답변입니다.

  1. 입력/출력 규칙의 공식 표준화:아니요
  2. 과거 출력 변화로 인한 파손:
  3. 향후 필터를 깨는 것은 절대 불가능합니다.아니요
  4. 변화로부터 자신을 보호하려면 어떻게 해야 합니까?보수적이다

"API"라고 말하면 (좋든 나쁘든) 필터 입력/출력 규칙에 대한 너무 많은 형식을 암시하는 용어를 사용하는 것입니다. 매우("매우"를 의미함) 광범위하게 쉽게 필터링할 수 있는 데이터에 대한 기본 규칙은 다음과 같습니다.

  • 각 입력 라인은 완전한 레코드입니다
  • 각 레코드 내에서 필드는 알려진 구분 문자로 구분됩니다.

전형적인 예는 /etc/passwd 형식입니다. 그러나 이러한 기본 규칙은 문자 그대로 따르는 것보다 어느 정도 더 자주 위반될 수 있습니다.

  • 여러 줄 입력 형식을 구문 분석하는 필터(종종 awk 또는 Perl로 작성됨)가 많이 있습니다.
  • 잘 정의된 필드 구조가 없는 입력 패턴(예: /var/log/messages)이 많으므로 보다 일반적인 정규식 기반 기술을 사용해야 합니다.

네 번째 질문인 출력 구조의 변화로부터 자신을 보호하는 방법은 실제로 당신이 할 수 있는 유일한 질문입니다.

  • 처럼@jw013 님이 말씀하셨습니다, posix 표준이 말하는 내용을 살펴보십시오. 물론 posix는 입력 소스로 사용하려는 모든 명령을 지정하지 않습니다.
  • 스크립트를 이식 가능하게 만들고 싶다면 설치한 일부 명령 버전의 특이성을 피하십시오. 예를 들어, 표준 Unix 명령의 많은 GNU 버전에는 비표준 확장이 있습니다. 이는 유용할 수 있지만 최대의 이식성을 원한다면 피해야 합니다.
  • 명령 인수 및 출력 형식의 하위 집합이 플랫폼 전반에 걸쳐 안정적인 경향이 있는지 알아보십시오. 불행하게도 이를 위해서는 시간이 지남에 따라 여러 플랫폼에 대한 액세스가 필요합니다. 이러한 차이점은 비공식적으로라도 어디에도 기록되지 않기 때문입니다.

결국, 걱정하는 문제로부터 자신을 완전히 보호할 수 없으며 특정 명령이 수행해야 하는 작업에 대한 "확정적인" 설명을 찾을 수 있는 단일 위치가 없습니다. 많은 쉘 스크립트, 특히 개인용 또는 소규모 사용을 위해 작성된 스크립트의 경우 이는 단순히 문제가 되지 않습니다.

답변4

사실상의 IO 표준(공백 및 널 분리 출력)만 있습니다.

호환성에 관해서는 일반적으로 개별 필터의 버전 번호 확인으로 되돌아갑니다. 많이 변경된 것은 아니지만 새로운 기능을 사용하고 여전히 이전 버전에서 스크립트를 실행하려면 어떻게든 "ifdef"해야 합니다. 실제로 테스트 사례를 수동으로 작성하는 경우를 제외하면 기능 보고 메커니즘이 없습니다.

관련 정보