덮어쓰기 전에 메시지를 표시하고 싶어서 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
을 지울 수도 있습니다 . 당신이 보는 모든 것은 라인 규율에 의해 처리되며, 입력 없이 그냥 거기에 있습니다. (또는 + , 또는 + ) 를 쳤을 때만 줄을 가져와서 인쇄합니다. 당신이 입력한 것 뒤의 줄 바꿈은 줄 규칙에서 온 것이고, 인쇄된 것 뒤의 줄 바꿈은 에서 온 것입니다 .BackspaceCtrlucat
EnterCtrlmCtrljcat
cat
cat
또는 무언가를 입력하고 Ctrl+를 눌러 개행 없이 d보낼 수 있습니다. cat
그러면 입력한 내용 뒤에 줄바꿈이 없고 cat
인쇄된 내용 뒤에 줄바꿈이 없습니다.
마찬가지로 에서 메시지가 표시되면 대화형으로 + +를 cp -i
입력할 수 있습니다 (왜 두 번인가요?yCtrldCtrld여기), cp
수락하고 줄 규칙에 따라 에코되는 y
것을 볼 수 있지만 y
개행은 없습니다(입력하지 않았기 때문에). cp
그 자체는 여기에 개행 문자를 인쇄하지 않습니다. 일반적으로(즉, 를 입력할 때 Enter) 줄 규칙 때문에 보이는 내용이 올바르게 보입니다(즉, 올바른 위치에 줄 바꿈이 있는 경우). cp
적절한 곳에 개행 문자를 삽입하여 출력이 보기 좋게 만드는 줄 규칙을 기대 한다고 말할 수 있습니다 .
요점은있다키보드와 사이에 줄 규칙이 있으면 cp -i
줄 바꿈을 포함하여 입력한 내용이 반영됩니다 Enter.
에서는 줄 규칙을 통해 입력한 것처럼 거의 입력을 받지만 이번에 yes | cp -i …
는 입력한 내용을 반영하는 줄 규칙과 같은 것은 없습니다 . 이것이 개행 문자(및 문자)가 없는 이유입니다 .cp
yEntercp
y
의 경우 yes '' | cp -i …
, 이후의 개행 문자는 not overwritten
실제로 에 의해 인쇄되었습니다 cp
. 누락된 것은 각 앞에 개행 문자입니다 not overwritten
. 가 없으면 프롬프트에 대한 응답으로 yes
바로 누르기만 하면 별도의 줄에 표시됩니다.Enternot overwritten
솔루션을 향하여
원하는 것을 얻으려면 에 들어가는 입력을 에코하는 것이 필요합니다 cp
. 언뜻 보면 실제 라인 규율인 것처럼 보입니다(여기에는 몇 가지 아이디어가 있습니다:출력이 터미널로 가는 것으로 생각하도록 명령을 속이는 방법; 우리는 속이고 싶지 않고 다음과 같이 터미널을 갖거나 와 사이에 cp
"부작용"을 원합니다 .tee
yes
cp
# both flawed
yes | socat STDIO EXEC:'cp -i …',pty
yes | tee >/dev/tty | cp -i …
yes
위의 방법은 출력을 즉시 생성하고 최대한 많이 생성하기 때문에 제대로 작동하지 않습니다 . yEnter이는 프롬프트가 있든 없든 사용자가 매시하는 것과 같습니다. 이것을 반향하면 질문에 게시한 것보다 출력이 훨씬 더 나빠 보입니다.
하나만 필요하다는 것을 미리 알았더라도 대신 을 yEnter사용하면 프롬프트가 인쇄되기 전에 입력이 표시되고 인쇄될 가능성이 높기 때문에(추가된 줄 규칙 또는 에 의해 ) 잘 작동하지 않습니다.echo y
yes
tee
cp
해결책
적절한 해결책은 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