Как повысить привилегии в середине конвейера?

8

Мое предположение было следующим:

echo "Generating some text" | su - -c cat >/output/file

Но suговорит:

su: must be run from a terminal

Что бы вы сделали?

х-юри
источник
Если вы нашли решение самостоятельно, добавьте его как ответ ниже.
Брайам
@Braiam Решение не заслуживает того, чтобы быть ответом.
x-yuri

Ответы:

8

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 в течение нескольких минут.
Винни
2

Просто чтобы вы знали - вы не ограничены одной командой на |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
mikeserv
источник
Я знаю это. Это мало или совсем не связано с вопросом, или я так думаю. Но как-то это привело меня к ответу :) Смотрите мой обновленный вопрос.
x-yuri
@ x-yuri Вы все еще можете поместить здесь документ в середине конвейера. эхо-то | {su 'сделай что-нибудь> /record.here'; } << ЗДЕСЬ | эхо конца канала \ n $ (кошка) \ n ТУТ \ n
mikeserv
На самом деле, я не думал об использовании cat внутри документа. Во всяком случае, вам не нужно группировать там.
x-yuri
@ х-юри - это зависит от того, что ты хочешь с этим делать. Вы можете использовать один или оба. Я только пытался продемонстрировать, что у вас есть варианты. Ответ Патрика здесь правильный, это просто другой, более запутанный способ. Этот вот-док делает группу, хотя - он группирует кошку в недоработке.
mikeserv
Под группировкой я имел в виду фигурные скобки .
x-yuri