Ma supposition était la suivante:
echo "Generating some text" | su - -c cat >/output/file
Mais su
dit:
su: must be run from a terminal
Qu'est-ce que tu ferais?
Ma supposition était la suivante:
echo "Generating some text" | su - -c cat >/output/file
Mais su
dit:
su: must be run from a terminal
Qu'est-ce que tu ferais?
Réponses:
sudo
soutient cela.
$ echo hello world | sudo cat
SUDO password:
hello world
La différence étant que vous sudo
demandez votre mot de passe utilisateur, pas le mot de passe root
(utilisateur cible). Cependant, si vous le souhaitez, vous pouvez modifier ce comportement avec la directive targetpw
(ou runaspw
ou rootpw
) dans sudoers.conf
.
Cependant, lire ce que vous essayez de faire, même si cela résout le problème de l'escalade des autorisations, ne fera pas ce que vous attendez. La signification /output/file
ne sera pas créée en tant qu'utilisateur root, elle sera créée / modifiée en tant qu'utilisateur.
La raison en est que la redirection de sortie du shell est effectuée avant d'appeler des commandes. Ainsi, le shell s'ouvre /output/file
puis passe ce fichier ouvert à su
/ sudo
(et par conséquent, cat
).
Cependant, vous pouvez le faire tee
à la place, car l' tee
utilitaire ouvrira le fichier lui-même.
echo "hello world" | sudo tee /output/file >/dev/null
Copie essentiellement tee
la sortie dans /output/file
et STDOUT, mais STDOUT est redirigé vers /dev/null
.
Vous pourriez également faire:
echo "hello world" | sudo sh -c 'cat > /output/file'
... qui est moins cryptique.
sudo -v
. Il vous demandera votre mot de passe si vous n'avez pas utilisé sudo depuis quelques minutes.
Juste pour que vous le sachiez - vous n'êtes pas limité à une seule commande par |pipe
:
this happens | then this | { then ; all of ; this too ; } | before this
Tous ces processus sont invoqués en même temps - mais ils attendent tous |pipe
avant eux avant de faire quoi que ce soit - tant qu'ils lisent le |pipe
tout, c'est-à-dire. Donc, si vous avez besoin d'évaluer une variable en cours de route ou de configurer une redirection, vous le pouvez. Prenez votre temps.
echo "it takes time" |
{ exec 4>|file ; cat >&4 ; } |
( sleep 1 && cat <file )
it takes time
Voici une autre façon:
echo "more of the same" |
( IFS= ; su -mc 'echo '"$(printf "'%s' " "`cat`")"' >|file' </dev/tty ) |
echo end of pipe
Si vous ne ( subshell )
le faites pas, la commande $(cat)
sera </dev/tty
également récupérée.
Mais si vous utilisez un here-doc, vous n'avez pas besoin de deux 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
PRODUCTION:
this is the beginning
of the pipeline
Password:
middle here
this is the end
of the pipeline
La plupart de ce qui précède est juste pour faire une démonstration. Tout ce dont vous avez vraiment besoin est:
su -c 'cat <&3 >./file' 3<<HERE | { wait as needed ; more stuff to do ; }
$(echo "something" | and other things)
HERE