Redirecting stdout to a file you don't have write permission on
Solution 1
Yes, using tee
. So echo test > /tmp/foo
becomes
echo test | sudo tee /tmp/foo
You can also append (>>
)
echo test | sudo tee -a /tmp/foo
Solution 2
To replace the content of the file with the output of echo
(like the >
shell redirection operator).
echo test | sudo dd of=/tmp/foo
To write into the file (at the beginning, though you can use seek
to output at different offsets) without truncating (like the 1<>
Bourne shell operator):
echo test | sudo dd of=/tmp/foo conv=notrunc
To append to the file (like >>
), with GNU dd
:
echo test | sudo dd of=/tmp/foo oflag=append conv=notrunc
See also GNU dd
's conv=excl
to avoid clobbering an existing file (like with set -o noclobber
in POSIX shells) and conv=nocreat
for the opposite (only update an existing file).
Solution 3
tee
is probably the best choice, but depending on your situation something like this may be enough:
sudo sh -c 'echo test > /tmp/foo'
Solution 4
While I agree, that | sudo tee
is the canonical way, sometimes sed (here assuming GNU sed
) may work:
cat sudotest
line 1
sudo sed -i '1iitest' sudotest && cat sudotest
itest
line 1
sudo sed -i '$aatest' sudotest && cat sudotest
itest
line 1
atest
-i
modifies the file in place. 1i
means insert before line 1. $a
means append after last line.
Or copy to xclipboard:
somecommand | xclip
sudo gedit sudotest
move cursor to desired place, click middle mouse button to insert, save
Solution 5
I have been kicking around in the back of my mind ideas for a similar problem, and came up with the following solutions:
sudo uncat
whereuncat
is a program that reads standard input and writes it to the file named on the command line, but I haven't writtenuncat
yet.sudocat
the variant ofsudoedit
that I haven't written yet that does a cleanersudo cat
orsudo uncat
.or this little trick of using
sudoedit
with an EDITOR that is a shell script#!/bin/sh # uncat cat > "$1"
which can be invoked as either
|sudo ./uncat file
or| EDITOR=./uncat sudoedit
but that has interesting side-effects.
Related videos on Youtube
Michael Mrozek
Updated on September 17, 2022Comments
-
Michael Mrozek over 1 year
When you attempt to modify a file without having write permissions on it, you get an error:
> touch /tmp/foo && sudo chown root /tmp/foo > echo test > /tmp/foo zsh: permission denied: /tmp/foo
Sudoing doesn't help, because it runs the command as root, but the shell handles redirecting stdout and opens the file as you anyway:
> sudo echo test > /tmp/foo zsh: permission denied: /tmp/foo
Is there an easy way to redirect stdout to a file you don't have permission to write to, besides opening a shell as root and manipulating the file that way?
> sudo su # echo test > /tmp/foo
-
Cristian Ciupitu over 13 yearsAnswer for a similar question from StackOverflow stackoverflow.com/questions/82256/…
-
-
Shawn J. Goff over 13 yearsTee will also output to stdout; sometimes you don't want the contents filling the screen. To fix this, do
echo test | sudo tee /tmp/foo > /dev/null
-
Adam Katz over 9 yearsclever! this alleviates the need to do
echo test | sudo tee /tmp/foo >/dev/null
to discard the output. -
Adam Katz over 9 yearsI may have to take that back;
dd
is unreliable for that unless you're using obscure GNU-only optionsiflag=fullblock oflag=fullblock
, which remove the elegance of this answer. I'll stick withtee
. -
umeboshi over 9 yearsdd is reliable with the non-obscure bs=1
-
ctrl-alt-delor about 9 years
cat
takes a list of files to concatinate, therefore uncat should take a list of files to un concatinate to. It would have to use magic to decide how much to put in each file. Alternative name includedog
,to-file
,redirect
. -
Wildcard over 8 yearsI can't think of any reason why I would want
uncat
when I havetee
. -
syntaxerror over 8 years@umeboshi But reliable only if you're experienced enough to know exactly what you're doing. For
dd
can be fairly dangerous (if not to say: devastating) if only a slight mistake was made. So for new users, I'd rather recommend thetee
method to be on the safe shore. -
Scott - Слава Україні about 8 yearsWell,
tee
has the trivial drawback that it writes its stdin to its stdout — which is trivially mitigated by redirecting the stdout to/dev/null
. Other alternatives includedd of=/tmp/foo
(mentioned in another answer), which writes status information to stderr, andcp /dev/stdin /tmp/foo
. -
edfuh over 7 yearsHow will you do it with heredoc?
-
Michael Mrozek over 7 yearsI'm not sure what advantage not writing to stdout presents, but you could just redirect the output to
/dev/null
if it were an issue -
user3299406 over 7 yearsOf course I can redirect to /dev/null, but the command is easier to read and type without the redirection. The advantage of not writing to stdout is that my terminal is not filled with rubbish.
-
user3299406 over 7 yearsI would not install a package to spare a redirection, but I regularly use sponge, so it is already there.
-
Stéphane Chazelas over 6 years@AdamKatz, in the case of
dd of=file
alone (withoutcount
/skip
...), it is reliable.iflag=fullblock
is not needed because heredd
writes on output what it has read on input. It doesn't matter if it was not full blocks. -
Andrew Henle about 6 yearsNote that
sed -i
does not actually modify the file in place - it creates a temporary file and renames it on exiting. So you won't be able to do something liketail -f ...
on the original file and see the output usingsed -i ...
while the pipeline is running -
user unknown about 6 years@AndrewHenle: Yes, since the size may be increased or shrinked, and since that's probably the case for most sed invocations, and you can't even - afaik - write to the same location on SSDs it's only a pseudo 'in place' operation. As a non native english speaker, may I ask for a brief expression, which isn't so likely misinterpreted? Just
-i creates a new file of same name
or is there something more compact? I guess I likein place
, because it explains thei
. The gnu-sed manpage calls it in place too and the long flag is--in-place
.