Мое предположение было следующим:
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.
Но если вы используете здесь документ, вам не нужно два cats:
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