rm 내장 프롬프트 옵션 -i 및 xargs를 사용하여 사용자에게 메시지를 표시하고 찾을 수 없습니다.

rm 내장 프롬프트 옵션 -i 및 xargs를 사용하여 사용자에게 메시지를 표시하고 찾을 수 없습니다.

나는 사용하고있다매개변수그리고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 file2cmd 변수에 명령을 전달하면 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 -istdin( 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 -okfind명령을 계속할지 묻는 옵션이 있습니다(프롬프트를 제외하면 와 같습니다 -exec).

touch file
find . -name 'file' -ok rm -f {} \;

산출

< rm ... ./file > ? _

답변3

여기서 문제는 (이 경우) 실행 중인 명령의 (표준 입력)이 stdin리디렉션되고 사용자 확인을 얻는 데 사용되는 파일 설명자라는 것입니다.xargsrm/dev/nullstdinrm

-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

관련 정보