강제로 덮어쓰고 새 줄로 덮어쓰려면 yes 명령을 어떻게 얻을 수 있나요?

강제로 덮어쓰고 새 줄로 덮어쓰려면 yes 명령을 어떻게 얻을 수 있나요?

덮어쓰기 전에 메시지를 표시하고 싶어서 cp를 사용하고 있습니다 -i.

cp(때때로 이나 이와 유사한 별칭을 사용할 수도 있으므로 cp항상 와 함께 발생합니다 -i).

모두 덮어쓴다고 말하고 싶을 수도 있습니다. 나는 이것이 기본값이라는 것을 알고 있지만 사용하고 있기 때문에 -i그것을 볼 수 없습니다.

나는 모두에게 '예' 또는 모두에게 '아니오'를 쉽게 할 수 있기를 원합니다.

별칭을 우회하는 방법을 묻는 것이 아니라 -i.

다음은 '예'를 강요하려는 나의 시도입니다 -i.

~$ mkdir test1
~$ cd test1
~/test1$ mkdir smalls
~/test1$ touch a.a
~/test1$ touch b.b
~/test1$ cp -i ?.? smalls
~/test1$ cp -i ?.? smalls
overwrite smalls/a.a? (y/n [n]) y
overwrite smalls/b.b? (y/n [n]) y
~/test1$ yes|cp -i ?.? smalls
overwrite smalls/a.a? (y/n [n]) overwrite smalls/b.b? (y/n [n]) ~/test1$ 
~/test1$ 
~/test1$ yes ''|cp -i ?.? smalls
overwrite smalls/a.a? (y/n [n]) not overwritten
overwrite smalls/b.b? (y/n [n]) not overwritten
~/test1$ 

그래서 나는 모두에게 'y'를 강요했지만 새로운 줄을 얻지 못했습니다.

내가 시도하면 yes ''| 예를 보내지 않습니다.

또한 'n'/'no'도 전달할 수 있기를 바랍니다.

yEnter그리고 파일이 많을 수 있으므로 수동으로 입력 하거나 nEnter각 파일을 찾고 있지 않습니다 .

명령 을 포함하지 않는 솔루션은 마음에 들지 않습니다 yes.

답변1

이것은 보이는 것만큼 쉽지 않습니다.

분석

실행 cp -i하고 응답할 때 대화형으로 프롬프트가 표시되면 입력 후 얻는 개행은 yEnter줄 규칙에서 나옵니다. 라인 규칙은 에코 y와 개행입니다.

cat터미널에서 단독을 실행하여 이 메커니즘을 관찰할 수 있습니다 . 입력을 기다리는 동안 긴 줄을 입력하고 문자( 사용 ) 또는 전체 줄( + 사용 ) cat을 지울 수도 있습니다 . 당신이 보는 모든 것은 라인 규율에 의해 처리되며, 입력 없이 그냥 거기에 있습니다. (또는 + , 또는 + ) 를 쳤을 때만 줄을 가져와서 인쇄합니다. 당신이 입력한 것 뒤의 줄 바꿈은 줄 규칙에서 온 것이고, 인쇄된 것 뒤의 줄 바꿈은 에서 온 것입니다 .BackspaceCtrlucatEnterCtrlmCtrljcatcatcat

또는 무언가를 입력하고 Ctrl+를 눌러 개행 없이 d보낼 수 있습니다. cat그러면 입력한 내용 뒤에 줄바꿈이 없고 cat인쇄된 내용 뒤에 줄바꿈이 없습니다.

마찬가지로 에서 메시지가 표시되면 대화형으로 + +를 cp -i입력할 수 있습니다 (왜 두 번인가요?yCtrldCtrld여기), cp수락하고 줄 규칙에 따라 에코되는 y것을 볼 수 있지만 y개행은 없습니다(입력하지 않았기 때문에). cp그 자체는 여기에 개행 문자를 인쇄하지 않습니다. 일반적으로(즉, 를 입력할 때 Enter) 줄 규칙 때문에 보이는 내용이 올바르게 보입니다(즉, 올바른 위치에 줄 바꿈이 있는 경우). cp적절한 곳에 개행 문자를 삽입하여 출력이 보기 좋게 만드는 줄 규칙을 기대 한다고 말할 수 있습니다 .

요점은있다키보드와 사이에 줄 규칙이 있으면 cp -i줄 바꿈을 포함하여 입력한 내용이 반영됩니다 Enter.

에서는 줄 규칙을 통해 입력한 것처럼 거의 입력을 받지만 이번에 yes | cp -i …는 입력한 내용을 반영하는 줄 규칙과 같은 것은 없습니다 . 이것이 개행 문자(및 문자)가 없는 이유입니다 .cpyEntercpy

의 경우 yes '' | cp -i …, 이후의 개행 문자는 not overwritten실제로 에 의해 인쇄되었습니다 cp. 누락된 것은 각 앞에 개행 문자입니다 not overwritten. 가 없으면 프롬프트에 대한 응답으로 yes바로 누르기만 하면 별도의 줄에 표시됩니다.Enternot overwritten


솔루션을 향하여

원하는 것을 얻으려면 에 들어가는 입력을 에코하는 것이 필요합니다 cp. 언뜻 보면 실제 라인 규율인 것처럼 보입니다(여기에는 몇 가지 아이디어가 있습니다:출력이 터미널로 가는 것으로 생각하도록 명령을 속이는 방법; 우리는 속이고 싶지 않고 다음과 같이 터미널을 갖거나 와 사이에 cp"부작용"을 원합니다 .teeyescp

# both flawed
yes | socat STDIO EXEC:'cp -i …',pty
yes | tee >/dev/tty | cp -i …

yes위의 방법은 출력을 즉시 생성하고 최대한 많이 생성하기 때문에 제대로 작동하지 않습니다 . yEnter이는 프롬프트가 있든 없든 사용자가 매시하는 것과 같습니다. 이것을 반향하면 질문에 게시한 것보다 출력이 훨씬 더 나빠 보입니다.

하나만 필요하다는 것을 미리 알았더라도 대신 을 yEnter사용하면 프롬프트가 인쇄되기 전에 입력이 표시되고 인쇄될 가능성이 높기 때문에(추가된 줄 규칙 또는 에 의해 ) 잘 작동하지 않습니다.echo yyesteecp


해결책

적절한 해결책은 cp -i …추가 pty를 사용하여 실행하되 메시지가 표시될 때만 입력하는 것입니다. expect(1)할 수있어. 이것은 빠르고 더러운 expect스크립트입니다:

#!/usr/bin/expect -f

set str [lindex $argv 0]
spawn -noecho cp -i {*}[lrange "$argv" 1 end]
while 1 {
   expect {
      "overwrite *\\?" { send "$str\r" }
      eof exit
   }
}

현지화된 사용자는 패턴 cp을 조정해야 합니다 "overwrite *\\?".

expect나는 에 대한 경험이 거의 없으며 스크립트가 차선책이거나 다소 결함이 있을 수 있음을 알려드립니다 . 개념 증명으로 취급하십시오. 스크립트를 cpx의 디렉토리에 저장하고 $PATH실행 가능하게 만들고( chmod +x cpx) 다음과 같이 사용하십시오.

cpx y ?.? smalls
# or
cpx n ?.? smalls

실제로는 쉘 별칭을 정의하는 것이 좋을 수 있습니다.

alias cpy='cpx y'
alias cpn='cpx n'

다음과 같이 사용하십시오.

cpy ?.? smalls
# or
cpn ?.? smalls

답변2

네이티브를 사용하기 위해 별칭을 우회하는 다양한 방법 cp:

  • 내장 명령을 사용하십시오.command cp
  • 명령의 전체 경로를 사용하십시오./bin/cp
  • 명령 이름의 아무 곳에나 \를 추가합니다. 예를 들면 다음과 같습니다.\cp
  • 명령을 인용하십시오: "cp"또는'cp'

답변3

'예 |'를 사용할 수 있습니다. 코드 앞에.

yes | cp -i ?.? smalls

관련 정보