구매하는 awk것은 나쁜 생각입니다

구매하는 awk것은 나쁜 생각입니다

cat /etc/os-release다음 메시지가 나타나면 :

PRETTY_NAME="Kali GNU/Linux Rolling"
NAME="Kali GNU/Linux"
ID=kali
VERSION="2018.1"
VERSION_ID="2018.1"
ID_LIKE=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.kali.org/"
SUPPORT_URL="http://forums.kali.org/"
BUG_REPORT_URL="http://bugs.kali.org/"

kaliBash 에서 어떻게 얻을 수 있나요 ID=? Bash 2018.1에서 어떻게 얻을 수 있나요 VERSION=?

답변1

구매하는 awk것은 나쁜 생각입니다

그러한 파일을 얻기 위해 쉘 스크립트 인터프리터를 사용하는 것은 좋지 않습니다.끝나고 나면 더 있어요악성 코드는 슈퍼유저 권한으로 실행될 셸 스크립트의 위치를 ​​숨기거나 재정의 및 변수 PATH와 같은 LANG기능을 도입할 수 있습니다 LD_LIBRARY_PATH.

% 고양이 /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (혁신적인 \$PATH로 확장됨)"
name="데비안 GNU/리눅스"
버전_ID="9"
버전="9(늘이기)"
ID=데비안
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
echo 1>&2 'install -m 0644 /etc/shadow /home/malefactor/etc/ 2>/dev/null'
PATH="/home/malefactor/bin:${PATH}"
%
%(소스/etc/os-release; 명령 -v start-stop-daemon;)
-m 0644 /etc/shadow /home/malefactor/etc/ 2>/dev/null 설치
/home/malefactor/bin/start-stop-데몬
%

조달은 실제로 정의의 의미 중 하나를 위반합니다 /etc/os-release. 즉, 매뉴얼을 인용하면 "변수 확장은 명시적으로 지원되지 않습니다"입니다.

마찬가지로 awkArchemar의 답변에 제공된 내용은 참조를 올바르게 처리하지 못합니다.어느값을 인용할 수 있습니다. Archemar의 답변은 VERSION질문의 값을 다루지 않으며 , 주어진 awk스크립트는 참조를 잘못 유지하고 이스케이프 시퀀스를 처리하지 않기 때문에 올바른 값을 제공하지 않습니다.

% awk -F= '$1=="버전" { 인쇄 $2 ;}' /etc/os-release
"9(스트레치)"      
% awk -F= '$1=="PRETTY_NAME" { $2 인쇄 ;}' /etc/os-release
"Debian GNU/Linux 9(혁신적인 \$PATH로 확장됨)"
%

/etc/os-release상당히 광범위한 참조가 실제로 허용되며 이스케이프 시퀀스를 적절하게 처리해야 합니다. awk여기서는 작업에 적합한 도구가 아닙니다.

파일에서 실제 조회 키가 누락된 경우 이미 설정된 변수가 결과에 누출되는 등 보다 미묘한 문제도 있습니다.

% (소스/etc/os-release; echo $LANG;)
-m 0644 /etc/shadow /home/malefactor/etc/ 2>/dev/null 설치
en_GB.UTF-8
%

ID또한 누락된 경우 PRETTY_NAME기본값으로 정의된다는 사실도 있습니다 . 게다가 /usr/lib/os-release처리해야 할 백업 문제도 있습니다.

다른 사람에게서 배우다

키와 동일한 값 할당뿐만 아니라 스타일 인용, 이스케이프 및 주석이 포함된 sh파일을 갖는 것은 매우 흔한 일입니다 . 일부 프로그래밍 언어에는 이를 직접 처리하는 라이브러리 기능이 있습니다. OpenBSD 5.6의 OpenBSD 규칙 변화에서 얻은 교훈 /etc/rc.conf은 이러한 라이브러리 기능(사용 가능한 경우)이나 전체 쉘 인터프리터만큼 강력하지 않은 특수 도구를 사용하여 이러한 파일을 처리하는 것이 더 현명하다는 것입니다.

쉘 스크립트에서는 다음이라는 도구를 사용합니다 read-conf.

% read_os() {
    -r /etc/os-release를 테스트하는 경우
    그 다음에
        Clearenv setenv "$1" "$2" read-conf /etc/os-release printenv "$1"
    기타
        Clearenv setenv "$1" "$2" read-conf /usr/lib/os-release printenv "$1"
    필리핀 제도
}
% read_os ID 리눅스
데비안
% read_os 버전
9(스트레치)
% read_os PRETTY_NAME 리눅스
Debian GNU/Linux 9(혁신적인 $PATH로 확장)
% read_os 경로
/home/malefactor/bin:${PATH}
% read_os LANG
%

위의 내용은 nosh 도구 세트에 내장된 명령인 setenv, read-conf및 명령을 사용하므로 각 명령인 , 및 명령은 환경 변수를 사용하지 않고도 체인에서 다음 명령을 찾을 수 있습니다. (내장된 줄을 추가하기 전에 검색을 피하기 위해 약간 긴 원래 한 줄을 조심스럽게 사용했습니다.printenvclearenvsetenvread-confPATHprintenv"`command -v printenv`"printenv 뒤쪽에감염된 구성 파일은 변경된 변수를 악의적으로 설정한 PATHclearenv해당 변수를 환경에서 제거합니다. )

추가 읽기

  • Theo de Ratet al. (2014-11-01).OpenBSD 5.6 변경 로그. OpenBSD.
  • 조나단 데보인 폴라드(2018). "read-conf". 수동. Nosh 툴셋. 소프트웨어.
  • 조나단 데보인 폴라드(2018). "clearenv". 수동. Nosh 툴셋. 소프트웨어.
  • 조나단 데보인 폴라드(2018). "setenv". 수동. Nosh 툴셋. 소프트웨어.
  • 조나단 데보인 폴라드(2018). "printenv". 수동. Nosh 툴셋. 소프트웨어.

답변2

파일을 가져와서 var의 값을 사용할 수 있습니다.

. /etc/os-release
echo $ID
echo $VERSION

아니면 시도해 보세요awk

awk -F= '$1=="ID" { print $2 ;}' /etc/os-release

어디

  • -F==를 구분 기호로 사용하도록 awk에 지시
  • $1=="ID"ID로 필터링
  • { print $2 ;}인쇄 값

답변3

ID=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"')
VERSION=$(grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"')
echo $ID:$VERSION

설명을 보려면 다른 두 가지 좋은 답변을 참조하십시오.

답변4

주의를 기울이다@JdeBP의 조언을 맹목적으로 해석하지 마세요.어느이러한 파일에는 쉘 코드가 포함되어 있지만 여전히 쉘 방식으로 참조를 처리합니다., 쉘 토큰화 및 인용문 제거를 수행하도록 설계된 매개변수 확장 플래그를 사용 zsh하여 이 작업을 수행할 수 있습니다 .zQ

contents=$(</etc/os-release)
shell_tokens=( ${(zZ[Cn])contents} )

set -o extendedglob
assignment_tokens=( ${(M)shell_tokens:#[[:IDENT:]]##=*} )
typeset -A field=()
for token ($assignment_tokens) field[${token%%=*}]=${(QX)token#*=}

그런 다음 zsh 스크립트에서 $field[VERSION]...를 사용할 수 있습니다.$field[VERSION_ID]

  • $(<file): ksh와 마찬가지로 파일 내용을 가져오고 후행 줄 바꿈을 제거합니다.
  • ${(z)scalar}모든 쉘 토큰²을 추출합니다.
  • Z[Cn]: z쉘 주석이 제거되고 개행 문자가 공백으로 처리되는 조정 플래그입니다.
  • ${array:#pattern}: 패턴과 일치하는 요소 이외의 배열 요소로 확장됩니다. 이 (M)플래그를 사용하면 추가 요소로만 확장됩니다 M.
  • [[:IDENT:]]:쉘 식별자에 허용되는 문자입니다.
  • ##: (with extendedglob): 하나 이상의 선행 원자( +확장 정규 표현식과 유사).
  • ${(QX)var}: 참조 레이어를 제거합니다( X그 안의 버그를 보고하기 위해).

1 ksh/bash와 달리 NUL 바이트는 예약되어 있습니다.

² 최상위 수준, 즉 명령 대체가 있는 경우 재귀적이지 않습니다.

관련 정보