stdin에서 읽고 파일에 쓰는 Unix 명령이 있습니까(예: 출력을 stdout으로 보내지 않고 tee)?

stdin에서 읽고 파일에 쓰는 Unix 명령이 있습니까(예: 출력을 stdout으로 보내지 않고 tee)?

한 시스템에서 다른 시스템으로 읽기/쓰기를 위해 루트가 필요한 파일을 복사하고 싶습니다. 내 현재 솔루션은 각 시스템에서 sudo를 사용하고 표시된 대로 tee를 사용하는 것입니다.

ssh host sudo cat /etc/somefile | sudo tee /etc/somefile > /dev/null

tee이것은 작동하지만 tee가 입력을 stdout으로 보내므로 출력을 /dev/null로 보내야 합니다 .

catUNIX 및 복사 명령을 살펴봤지만 cp답을 찾지 못했습니다.
바라보다https://man7.org/linux/man-pages/man1/cp.1.html
그리고https://man7.org/linux/man-pages/man1/cat.1.html


sudo업데이트: 이제 이 솔루션에는 지원이 필요하므로 간단한 사용 솔루션은 cat작동하지 않는다는 점을 명시해야 한다는 것을 깨달았습니다 .

예를 들어,

ssh host sudo cat /etc/somefile | sudo cat > /etc/somefile

디렉토리 /etc는 루트(필자의 경우)만 쓸 수 있고 파일 리디렉션은 > /etc/somefile현재 사용자(/etc에 쓸 수 있는 권한이 없는 사용자)에서 실행되기 때문에 실패합니다.

답변1

가지다:

sh -c 'exec cat > file'

또는 모든 $files에 대해 환경 변수로 전달됩니다.

sudo FILE="$file" sh -c 'exec cat > "$FILE"'

또는 매개변수로:

sudo sh -c 'exec cat > "$1"' sh "$file"

( sh들어가는 인라인 스크립트의 내용 $0)$file$1

( 다음에서 여는 >>대신 참조하세요.>추가의모드 또는 1<>잘림 없이(그리고 읽기+쓰기 모드에서) 열어 파일을 제자리에 덮어씁니다( dd's conv=notrunc).

아무튼 하세요아니요하다:

sudo sh -c "cat>$file 실행"

$file왜냐하면 셸 구문에 특수 문자(예: 공백, ;...)를 포함하면 실패하고 $명령 주입 취약점이 발생하기 때문입니다.


게다가:

dd bs=65536 of=file

( 전송 보고를 억제하기 위해 status=noneGNU와 호환되거나 구현되었습니다 dd. 파일을 여는 방법을 제어하는 ​​더 많은 옵션이 있으며 그 목록은 구현에 따라 다릅니다 dd.)


대부분의 시스템에서:

cp /dev/stdin file

moreutils더 있다

sponge file

sort최소한 GNU를 사용하고 텍스트 입력 시:

sort -mo file

텍스트 입력(또는 sed텍스트가 아닌 것을 처리할 수 있는 구현)을 사용하세요.

sed -n 'w file'

텍스트 입력 사용:

awk '{print > "file"}'

또는 GNU를 사용하십시오 awk:

gawk -v ORS= '{print $0 RT > "file"}'

ssh여기에서 루트로 로컬 파일을 열고 일반 사용자로 실행할 수도 있습니다 .

sudo zsh -c '
  USERNAME=$SUDO_USER ssh host 'sudo cat /etc/somefile' > /etc/somefile'

이는 데이터가 추가 파이프를 통해 이동할 필요가 없음을 의미합니다.

또한 즉시 압축을 사용 xz하고 pixz파일로 압축 해제 지원을 통해 로컬로 압축을 풀 수도 있습니다.

ssh host 'sudo xz -0 -c /etc/somefile' | sudo pixz -tdo /etc/somefile

답변2

여러 개의 파일이 있고 대상의 동일한 위치에 있어야 하는 경우 tar여기에서 파일을 다른 디렉터리에 복사할 수 있지만 파이프도 ssh어떤 방식으로 관련될 수 있습니다. 그래도 문제가 해결되지 않으면 p파일 권한이나 일부 압축 플래그를 유지할 수 있습니다.ssh

$ mkdir output
$ echo foo > foo
$ echo bar > bar
$ tar cf - foo bar | ( cd output && tar xf - )
$ cat output/*
bar
foo

tar구현이 시스템마다 다를 경우 이식성 문제가 발생할 수 있습니다.

답변3

cat요구 사항을 따르는 가장 간단한 절차입니다. 특히 cat -표준 입력에서 데이터를 읽도록 명령에 지시합니다.

sudo파이프 명령의 왼쪽은 명확하지 않습니다 /etc/somefile. 대답에 대한 최선의 추측은 다음과 같습니다.

sudo cat /etc/somefile | ssh me@otherhost 'sudo cat - > /etc/somefile'

관련 정보