파일 이름을 인용하면`xargs sudo rm -rf`를 실행하기에 충분한 보안이 있습니까?


10

폴더의 마지막 두 파일을 제외한 모든 파일을 삭제하는 스크립트를 작성했습니다.

#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder \
    | head -n -2 \
    | xargs printf -- "'/path/to/some/folder/%s'\n" \
    | xargs sudo rm -rf

이 스크립트는 매일 크론 작업으로 실행됩니다.

추론은 다음과 같습니다.

  1. 사용하여 모든 파일 목록을 얻습니다 ls -1(한 줄에 하나의 파일을 얻습니다).

  2. head -n -2;를 사용하여 목록에서 마지막 두 개를 제거하십시오 .

  3. ls상대 경로를 인쇄 하므로 xargs printf폴더 경로를 앞에 붙여서 절대 경로로 만드십시오.

  4. sudo rm -rf사용하여 보내십시오 xargs.

누구나이 폴더에 액세스 할 수 있으므로 누구나이 폴더에서 파일을 작성하고 삭제할 수 있습니다.

문제는 : sudo rm -rf 무섭다. xargs sudo rm -rf엄청 무섭다.

실수로 또는 의도적으로 삭제 될 영리한 파일을 만들어 다른 폴더 / 시스템을 손상시킬 수있는 사람이 아무도 없도록하려고합니다. 잘 모르겠습니다.

file with / spaces.txt

그것은 매우 무서운 결과를 초래할 수 있습니다 sudo rm -rf /.

편집 : 내 실수, 파일 이름에 포함 할 수 없으므로이 /특정 문제는 발생하지 않지만 다른 위험이 있는지 여부에 대한 질문은 여전히 ​​존재합니다.

이것이 내가 사용하는 이유 --quoting-style=shell-always입니다. 공백이있는 파일의 트릭을 방지해야합니다. 그러나 이제 누군가 파일 이름에 공백 따옴표가있는 영리한 사람이 있는지 궁금합니다 .

내 스크립트는 안전합니까?


참고 :을 sudo사용하여 매핑 된 네트워크 드라이브에서 원격으로 폴더를 액세스하고 있기 때문에 mountsudo 없이는 폴더를 사용할 수 없기 때문에 필요 합니다 .


3
당신은 같은 일을 고려 했습니까 printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm?
steeldriver

문자가있는 파일 수 /이름을 내가 여기 다시를 달성하기 위해 노력하고 생성
조지 Udosen

3
@George 아니요, 파일 이름에는 슬래시가 포함될 수 없습니다.
wjandrea

OP가 영리한 사람이라고 할 때 궁금한
점이 있습니다

6
단순히 ls출력을 구문 분석하기 때문에 인용으로도 이미 잘못 작성된 명령입니다. ls또한 사용 순서를 정렬 로케일, 난의 목적을 무엇을 볼 수 없습니다, 그래서 생각 head지난 2 (당신이 없애려고하지 않는 한 제거에 ...있는이 IIRC 인수로 허용되지 않습니다 rm어쨌든. 그냥 사용 find /path/to/folder -type f delete. 그리고는 더 sudo당신이 크론에서 실행하는 경우 - 크론은 루트 레벨에 이미
세르지 Kolodyazhnyy

답변:


10

Linux에서 모든 문자는 다음을 제외하고 유효한 파일 이름 구성 문자입니다.

  • \0 (ASCII NUL) : C에서 문자열 종료에 사용
  • / (슬래시) : 경로 분리에 사용

예를 들어 \n파일 이름에서 개행 ( )을 처리 합니까? ( 힌트 : 아니오 ).

몇 가지 참고 사항 :

  • 파싱하지 마십시오 ls. 전용 도구 사용 (대부분의 사용 사례에는 하나 이상)
  • 파일 이름을 다룰 때, 그러한 데이터를 처리하는 거의 모든 GNU 도구가 제공하는 NUL 분리 출력을 활용하십시오
  • 배관시주의 사항, 두 프로그램 모두 NUL 분리를 이해할 수 있는지 확인하십시오
  • 당신이 전화 할 때마다, 당신이 xargs도망 갈 수 있는지보십시오 find ... -exec; 대부분의 경우 find혼자서도 괜찮을 것입니다

나는 이것이 당신을 위해 지금 갈 것이라고 생각합니다. steeldriver는 이미 주석 ( printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm) 에서 NUL 분리 아이디어를 제공했으며 , 이것을 시작점으로 사용하십시오.


귀하의 답변에 감사드립니다 :) 나는 당신이 단지 언급하는 대신에 강철 운전자의 의견을 인용해야한다고 생각합니다 (의견은 영구적이지 않기 때문에). 나는으로 살펴 보겠습니다 find뿐만 아니라 제안을 주셔서 감사합니다.
Pedro A

하지만 한 가지 질문이 있습니다. "상상할 수없는 것처럼 접근하지 않을 것입니다"- "안전하지 않은"또는 "안전하지 않은"과 같이 "작동하지 않는 경우가 많습니다."라는 말의 의미를 이해하지 못합니까? "귀하의 접근 방식"은 악의적 인 사용자가 아닌 나를 지칭하기 때문에 귀하의 이전 진술은 내가 선호하는 것이므로 혼동됩니다.
Pedro A

@PedroA 당신은 당신입니다 :) 내가 말했듯이, 언급 된 두 문자를 제외한 모든 문자가 유효하기 때문에 ls파싱 ​​접근법이 실패 하는 수많은 경우를 상상할 수 있습니다. 예를 들어 파일 이름의 줄 바꿈을 고려한 적이 있습니까?
heemayl

오, 파일 이름의 줄 바꿈 ... 나는 그것을 생각하지 못했습니다. 당신의 답변에 그것을 추가하는 것이 마음에 들지 않는다면 :) 또한, 죄송합니다.하지만 무엇을 head -z합니까? 그것은 말도 안되는 소리 그러나 나는이없는 maninfo내 CoreOS 컨테이너 리눅스에 ... 중 하나를 인터넷에서 찾을 수 없습니다. 나는head: invalid option 'z'
Pedro A

@PedroA 줄 바꿈이 많은 등이 있습니다, 하나의 경우입니다 당신이 짐작 하듯이 . GNU가 필요합니다 (GNU head와 함께 제공 coreutils). 온라인 버전은 다음과 같습니다. manpages.ubuntu.com/manpages/xenial/man1/head.1.html
heemayl

3

xargs 작은 따옴표, 큰 따옴표 또는 백 슬래시를 사용하여 임의의 인수 ¹를 허용하지만 Bourne과 같은 쉘의 따옴표 구문과 다른 구문을 사용하여 일부 인용을 지원합니다.

lsUbuntu에서 찾은 GNU 구현 에는 xargs입력 형식 과 호환되는 인용 모드가 없습니다 .

그는 ls --quoting-style=shell-always경우 ksh93, 배쉬 및 구문을 인용 zsh을 조개와 호환되지만 때에 만의 출력 ls과 동일한 로케일에서 쉘에 의해 해석되는 ls경우가 출력을했다. 또한 BIG5, BIG5-HKSCS, GBK 또는 GB18030을 사용하는 것과 같은 일부 로케일은 피해야합니다.

따라서 해당 쉘을 사용하면 실제로 다음을 수행 할 수 있습니다.

typeset -a files
eval "files=($(ls --quoting-style=shell-always))"
xargs -r0a <(printf '%s\0' "${files[@]:0:3}") ...

그러나 그것은 다음과 같은 이점이 거의 없습니다.

files=(*(N))                 # zsh
files=(~(N)*)                # ksh93
shopt -s nullglob; files=(*) # bash

유용하게 사용되는 유일한 경우는 mtime / atime / ctime 또는 / 별로 파일을 정렬하는 -t옵션 을 사용하려는 경우 입니다. 그러나 그때조차도 의을 사용할 수도 있습니다 .ls-S-Vzsh

files=(*(Nom))

예를 들어 , mtime으로 파일을 정렬합니다 ( oLfor -Snfor 사용 -V).

가장 최근에 수정 된 두 개의 일반 파일을 제외한 모든 파일을 제거하려면

rm -f -- *(D.om[3,-1])

¹ 여전히 일부 길이 제한 ( execve()GNU 이외의 xargs구현에서는 훨씬 낮은 임의의 구현)이 있으며 일부 GNU 이외의 xargs구현에서는 유효한 문자를 형성하지 않는 바이트 시퀀스를 포함하는 입력이 질식됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.