@geekosaur가 설명했듯이 셸은 명령을 실행하기 전에 리디렉션을 수행합니다. 이것을 입력 할 때 :
sudo foo >/some/file
현재 쉘 프로세스는 /some/file
쓰기를 위해 먼저 열려고 시도하는 자체 복사본을 만들고 성공하면 해당 파일 설명자를 표준 출력으로 만들고 성공한 경우에만 실행 sudo
합니다. 이것은 첫 번째 단계에서 실패합니다.
허용되는 경우 (sudoer 구성은 종종 실행중인 셸을 배제 함) 다음과 같이 할 수 있습니다.
sudo bash -c 'foo >/some/file'
그러나 일반적으로 좋은 해결책은 | sudo tee
대신 >
및 | sudo tee -a
대신 사용 하는 것입니다 >>
. 리디렉션이 sudo
처음에 필요한 유일한 이유 인 경우 특히 유용합니다 . 결국 불필요하게 루트로 프로세스를 실행하는 sudo
것은 피하기 위해 만들어진 것입니다. 그리고 echo
루트로 실행 하는 것은 어리석은 일입니다.
echo '[archlinuxfr]' | sudo tee -a /etc/pacman.conf >/dev/null
echo 'Server = http://repo.archlinux.fr/$arch' | sudo tee -a /etc/pacman.conf >/dev/null
echo ' ' | sudo tee -a /etc/pacman.conf >/dev/null
이름이 지정된 파일 과 자체 표준 출력 모두에 출력을 보내기 > /dev/null
때문에 마지막에 추가 했으며 터미널에서 볼 필요가 없습니다. 합니다 ( 명령은. 그것의 이름을 가져옵니다 곳이다, 물리적 파이프 라인에서 "T"커넥터와 같은 역할) 그리고 (작은 따옴표로 전환 ... (대신 두 배의) ... 모든 것이 문자 그대로 내가 그래서) 의 앞에 백 슬래시를 넣어하지 않았다 에서 . (따옴표 또는 백 슬래시가 없으면 셸 매개 변수 값으로 대체됩니다. 아마도 존재하지 않을 것입니다.이 경우는 아무 것도 대체되지 않고 사라집니다.)tee
tee
'
'
"
"
$
$arch
$arch
arch
$arch
따라서 .NET을 사용하여 루트로 파일에 쓰는 작업을 처리합니다 sudo
. 이제 쉘 스크립트에서 줄 바꿈이 포함 된 텍스트를 출력하는 방법에 대한 긴 여담을 살펴 보겠습니다. :)
BLUF를 위해 내가 선호하는 솔루션은 위의 sudo tee
명령에 here-document를 입력하는 것입니다 . 다음 필요가 없다 cat
거나 echo
또는 printf
전혀 다른 명령 또는. 작은 따옴표는 센티넬 소개로 이동 <<'EOF'
했지만 동일한 효과가 있습니다. 본문은 리터럴 텍스트로 처리되므로 그대로 $arch
둡니다.
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
하지만 그렇게했지만 대안이 있습니다. 다음은 몇 가지입니다.
한 echo
줄에 하나씩 붙일 수 있지만 모두 하위 셸로 그룹화하므로 한 번만 파일에 추가하면됩니다.
(echo '[archlinuxfr]'
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
에 추가 -e
하는 경우 echo
(그리고 POSIX가 아닌 확장을 지원하는 셸을 사용하고있는 경우) 다음을 사용하여 줄 바꿈을 문자열에 직접 포함 할 수 있습니다 \n
.
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
그러나 위에서 말했듯이 POSIX에서 지정한 동작이 아닙니다. 셸은 리터럴 -e
뒤에 리터럴 \n
s 무리가있는 문자열을 에코 할 수 있습니다 . 이를 수행하는 POSIX 방식은 printf
대신 사용하는 것입니다 echo
. 인수를 자동으로 처리 echo -e
하지만 끝에 자동으로 줄 바꿈을 추가하지 않으므로 추가로 추가해야합니다 \n
.
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n \n' |
sudo tee -a /etc/pacman.conf >/dev/null
두 솔루션 중 하나를 사용하여 명령이 인수 문자열로 가져 오는 것은 두 문자 시퀀스 \n
를 포함하며이를 개행 문자로 변환하는 것은 명령 프로그램 자체 ( printf
또는 내부 코드 echo
)에 달려 있습니다. 많은 최신 셸에서 ANSI 따옴표 $'
... 를 사용하는 옵션이 있습니다.이 옵션은 명령 프로그램이 문자열을보기 전에 리터럴 줄 바꿈 으로 '
같은 시퀀스를 변환 합니다. 즉, 이러한 문자열은 일반 old -less를 포함하여 모든 명령과 함께 작동합니다 .\n
-e
echo
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
그러나 echo -e
ANSI 따옴표 보다 이식성이 높지만 여전히 POSIX가 아닌 확장입니다.
그리고 이것들이 모두 옵션이지만 tee <<EOF
위 의 직접적인 솔루션을 선호합니다 .