![rm 내장 프롬프트 옵션 -i 및 xargs를 사용하여 사용자에게 메시지를 표시하고 찾을 수 없습니다.](https://linux55.com/image/34698/rm%20%EB%82%B4%EC%9E%A5%20%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8%20%EC%98%B5%EC%85%98%20-i%20%EB%B0%8F%20xargs%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EC%82%AC%EC%9A%A9%EC%9E%90%EC%97%90%EA%B2%8C%20%EB%A9%94%EC%8B%9C%EC%A7%80%EB%A5%BC%20%ED%91%9C%EC%8B%9C%ED%95%98%EA%B3%A0%20%EC%B0%BE%EC%9D%84%20%EC%88%98%20%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
나는 사용하고있다매개변수그리고RM그리고찾다find로 정의된 특정 패턴을 따르는 파일을 삭제하려면 다음과 같이 하십시오.
touch file
find . -name file | xargs rm
위의 코드는 모두 잘 작동하지만 rm의 -i 옵션을 입력하고 다음을 실행하면:
touch file
find . -name file | xargs rm -i
인쇄:
rm: 일반 빈 파일 "./file7"을 삭제하시겠습니까? 사용자@호스트:$
y 또는 n을 입력할 수 없습니다. 따라서 파일은 삭제되지 않습니다.
여기서 문제가 무엇입니까?
또한 xargs -p 매개변수가 작동한다는 것도 알고 있지만 더 일반적입니다. 즉, 사용자에게 특정 명령을 실행하라는 메시지가 표시되는데, 이는 사용자가 조작하기에 불편하다.
편집: 쉘 스크립트에서 이것을 사용할 때 내가 원하는 명령을 실행했지만 바람직하지 않은 find 결과도 인쇄했다는 것을 알았습니다.
또한 ls file2
cmd 변수에 명령을 전달하면 file2에 대한 사양이 구체적으로 인쇄되지 않습니다. 를 입력할 때도 같은 일이 발생합니다
rm -i file2
. 디렉토리의 모든 파일을 삭제하라는 메시지가 표시됩니다.
이것은 내 스크립트입니다.
#!/bin/bash
touch file{1..9} # Create 9 files named file1,file2...file9
echo -n 'command: ' # Prompt user
read -e cmd # read command
find . -exec ${cmd} '{}' +
내가 생각할 수 있는 유일한 해결책은 사용자에게 선호하는 모드를 선택하라는 메시지를 개별적으로 표시하는 것입니다. 그런 다음 해당 패턴을 변수에 저장하고 매개변수로 전달합니다.찾다당당한-이름옵션.
이 같은:
#!/bin/bash
touch file{1..9} # Create 9 files named file1,file2...file9
echo -n 'command: ' # Prompt user for command
read -e cmd # read command
echo -n 'pattern: ' # Prompt user for pattern
read -e pattern
find . -name "$pattern" -exec ${cmd} '{}' +
하지만 이 솔루션을 사용하더라도찾다출력은 계속 인쇄되며, 패턴 필드가 비어 있는 경우(즉, 사용자가 패턴을 사용하고 싶지 않은 경우) 문제가 발생합니다.
어떤 아이디어가 있나요?
답변1
xargs는 stdin에서 데이터를 읽습니다. rm을 사용할 때 rm -i
stdin( try )에서 응답을 읽으려고 시도 touch test && echo y | r -i test ; ls test
하지만 stdin은 xargs에 의해 닫히므로(가정) 프롬프트에서 ctrl-d를 누른 것처럼 rm이 반응합니다.
또 다른 해결책은 find의 -exec 옵션일 수 있습니다.
touch test
find . -name test -exec rm -i {} \;
답변2
당신은 그것을 사용할 수 있습니다POSIX -ok
find
명령을 계속할지 묻는 옵션이 있습니다(프롬프트를 제외하면 와 같습니다 -exec
).
touch file
find . -name 'file' -ok rm -f {} \;
산출
< rm ... ./file > ? _
답변3
여기서 문제는 (이 경우) 실행 중인 명령의 (표준 입력)이 stdin
리디렉션되고 사용자 확인을 얻는 데 사용되는 파일 설명자라는 것입니다.xargs
rm
/dev/null
stdin
rm
이 -a
옵션을 사용하면 rm이 이전에 find 명령으로 생성된 중간 파일에서 파일 목록을 가져올 수 있습니다(이 -a
옵션을 사용하면 xargs
영향을 받지 않음 stdin
). 어쨌든 중간 파일이 필요하기 때문에 이것이 실제로 원하는 것이 아닐 수도 있다는 것을 알고 있습니다. 다음을 사용하여 원하는 것과 유사한 보다 직접적인 방법을 얻을 수 있습니다.
for i in $(find . -name file); do rm -i "$i"; done
답변4
비슷한 문제가 있었는데 명령이 나올 때 놀랐습니다.
find . -type f -name "*.txt" | xargs rm
이 패턴과 일치하는 읽기 전용 파일이 실수로 삭제되었습니다.
나중에 매뉴얼 페이지에서 설명을 찾았습니다 rm
.
파일이 쓰기 가능하지 않고 표준 입력이 터미널이고 -f 또는 --force 옵션이 제공되지 않거나 -i 또는 --interactive=always 옵션이 제공되면 rm은 사용자에게 파일을 삭제할지 묻는 메시지를 표시합니다.
프롬프트를 표시하는 조건 중 하나는 표준 입력이 터미널이고 다른 명령의 출력을 rm
.
중요한 교훈: stdin이 터미널이 아닌 경우 rm
읽기 전용 파일은 경고 없이 삭제됩니다!
find
제 경우에는 쓰기 가능한 파일만 반환하도록 명령을 수정하는 것이 해결책이었습니다 .
find . -type f -writable -name "*.txt" | xargs rm