아치의 pacman.conf 파일에 저장소 소스 추가를 자동화하려고하지만 echo
쉘 스크립트에서 명령을 사용합니다 . 그러나 다음과 같이 실패합니다.
sudo echo "[archlinuxfr]" >> /etc/pacman.conf
sudo echo "Server = http://repo.archlinux.fr/\$arch" >> /etc/pacman.conf
sudo echo " " >> /etc/pacman.conf
-bash: /etc/pacman.conf: Permission denied
vim을 사용하여 수동으로 /etc/pacman.conf를 변경하면
sudo vim /etc/pacman.conf
으로 vim을 종료 :wq
하면 모든 것이 잘 작동하며 내 pacman.conf는 “Permission denied”불만없이 수동으로 업데이트되었습니다.
왜 그렇습니까? 그리고 어떻게 sudo echo
일할 수 있습니까? (btw, 나도 사용해 보았지만 sudo cat
권한이 거부되어 실패했습니다)
답변
문제는 리디렉션이에서가 아니라 원래 셸에서 처리되고 있다는 것 sudo
입니다. Shells는 마음을 읽을 수 없으며 그 특정 >>
이 자신을 sudo
위한 것이 아니라위한 것인지를 알지 못합니다.
다음을 수행해야합니다.
- 리디렉션을 인용하십시오 (그래서 전달됩니다
sudo)
- 및 사용
sudo -s
(즉, 그래서sudo
인용 리디렉션을 처리하는 쉘을 사용합니다.)
답변
@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
.
# NON-POSIX - NOT RECOMMENDED
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
위 의 직접적인 솔루션을 선호합니다 .
답변
http://www.innovationsts.com/blog/?p=2758
위의 지침이 명확하지 않기 때문에 해당 블로그 게시물의 지침을 사용하고 있습니다. 예제를 통해 수행해야하는 작업을 더 쉽게 확인할 수 있습니다.
$ sudo 고양이 /root/example.txt | gzip> /root/example.gz
-bash : /root/example.gz : 권한이 거부되었습니다.
오류를 일으키는 것은 파이프 라인에서 두 번째 명령 (gzip 명령)입니다. 그것이 -c 옵션과 함께 bash를 사용하는 우리의 기술이 들어오는 곳입니다.
$ sudo bash -c ‘cat /root/example.txt | gzip> /root/example.gz ‘
$ sudo ls /root/example.gz
/root/example.gz
ls 명령의 출력에서 압축 파일 생성이 성공했음을 알 수 있습니다.
두 번째 방법은 명령 문자열을 bash에 전달한다는 점에서 첫 번째 방법과 유사하지만 sudo를 통해 파이프 라인에서 수행합니다.
$ sudo rm /root/example.gz
$ echo “cat /root/example.txt | gzip> /root/example.gz”| sudo bash
$ sudo ls /root/example.gz
/root/example.gz
답변
sudo bash -c 'echo "[archlinuxfr]" >> /etc/pacman.conf'
답변
1 단계 bash 파일 ( write_pacman.sh
)에 함수 생성
#!/bin/bash
function write_pacman {
tee -a /etc/pacman.conf > /dev/null << 'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/\$arch
EOF
}
'EOF'
$arch
변수를 해석하지 않습니다 .
STE2 소스 bash 파일
$ source write_pacman.sh
STEP 3 기능 실행
$ write_pacman
답변
추가 파일 (sudo cat) :
cat <origin-file> | sudo tee -a <target-file>
파일에 에코 추가 (sudo echo) :
echo <origin> | sudo tee -a <target-file>
(추가) 출력 무시 :
echo >origin> | sudo tee -a <target-file> >/dev/null