Мое предположение было следующим:
echo "Generating some text" | su - -c cat >/output/file
Но su
говорит:
su: must be run from a terminal
Что бы вы сделали?
Мое предположение было следующим:
echo "Generating some text" | su - -c cat >/output/file
Но su
говорит:
su: must be run from a terminal
Что бы вы сделали?
Ответы:
sudo
поддерживает это.
$ echo hello world | sudo cat
SUDO password:
hello world
Разница в том, что sudo
запрашивается ваш пароль пользователя, а не пароль root
(целевого пользователя). Однако, если вы хотите, вы можете изменить это поведение с помощью директивы targetpw
( runaspw
или rootpw
) в sudoers.conf
.
Однако, читая то, что вы пытаетесь сделать, пока это решает проблему эскалации разрешений, это не будет делать то, что вы ожидаете. Значение /output/file
не будет создано как пользователь root, оно будет создано / изменено как ваш пользователь.
Причина этого заключается в том, что перенаправление вывода оболочки выполняется до вызова каких-либо команд. Таким образом, оболочка открывается /output/file
и затем передает этот открытый файл в su
/ sudo
(и, следовательно, cat
).
Однако вы можете использовать tee
это вместо этого, так как tee
утилита откроет сам файл.
echo "hello world" | sudo tee /output/file >/dev/null
В основном tee
копирует выходные данные в /output/file
и STDOUT, однако STDOUT перенаправляется в /dev/null
.
Вы также можете сделать:
echo "hello world" | sudo sh -c 'cat > /output/file'
... что менее загадочно.
sudo -v
. Он спросит ваш пароль, если вы не использовали sudo в течение нескольких минут.
Просто чтобы вы знали - вы не ограничены одной командой на |pipe
:
this happens | then this | { then ; all of ; this too ; } | before this
Все эти процессы вызываются одновременно - но все они ждут |pipe
перед тем, как на самом деле что-то делать, до тех пор, пока они вообще читают |pipe
, то есть. Так что, если вам нужно оценить переменную midstream или настроить перенаправление, вы можете. Не торопись.
echo "it takes time" |
{ exec 4>|file ; cat >&4 ; } |
( sleep 1 && cat <file )
it takes time
Вот еще один способ:
echo "more of the same" |
( IFS= ; su -mc 'echo '"$(printf "'%s' " "`cat`")"' >|file' </dev/tty ) |
echo end of pipe
Если вы этого не сделаете, ( subshell )
команда $(cat)
получит </dev/tty
.
Но если вы используете здесь документ, вам не нужно два cat
s:
rm ./file
su -c 'cat <&3 >|./file; echo "middle here"' 3<<HERE >&2 | {\
until [ -s ./file ] ; do sleep 1 ; done ;\
sed 's/beginning/end/' ./file ; }
$(echo "this is the beginning" | sed 'a\of the pipeline' | tee /dev/stderr)
HERE
ВЫВОД:
this is the beginning
of the pipeline
Password:
middle here
this is the end
of the pipeline
Большинство из вышеперечисленного просто для демонстрации этого. Все, что вам действительно нужно, это:
su -c 'cat <&3 >./file' 3<<HERE | { wait as needed ; more stuff to do ; }
$(echo "something" | and other things)
HERE