This is a pretty simple question, at least it seems like it should be, about sudo permissions in Linux.
There are a lot of times when I just want to append something to /etc/hosts
or a similar file but end up not being able to because both >
and >>
are not allowed, even with root.
Is there someway to make this work without having to su
or sudo su
into root?
This question is related to
bash
shell
scripting
permissions
sudo
Use tee --append
or tee -a
.
echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list
Make sure to avoid quotes inside quotes.
To avoid printing data back to the console, redirect the output to /dev/null.
echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list > /dev/null
Remember about the (-a
/--append
) flag!
Just tee
works like >
and will overwrite your file. tee -a
works like >>
and will write at the end of the file.
The problem is that the shell does output redirection, not sudo or echo, so this is being done as your regular user.
Try the following code snippet:
sudo sh -c "echo 'something' >> /etc/privilegedfile"
The problem is that the shell does output redirection, not sudo or echo, so this is being done as your regular user.
Try the following code snippet:
sudo sh -c "echo 'something' >> /etc/privilegedfile"
The problem is that the shell does output redirection, not sudo or echo, so this is being done as your regular user.
Try the following code snippet:
sudo sh -c "echo 'something' >> /etc/privilegedfile"
The problem is that the shell does output redirection, not sudo or echo, so this is being done as your regular user.
Try the following code snippet:
sudo sh -c "echo 'something' >> /etc/privilegedfile"
The issue is that it's your shell that handles redirection; it's trying to open the file with your permissions not those of the process you're running under sudo.
Use something like this, perhaps:
sudo sh -c "echo 'something' >> /etc/privilegedFile"
The issue is that it's your shell that handles redirection; it's trying to open the file with your permissions not those of the process you're running under sudo.
Use something like this, perhaps:
sudo sh -c "echo 'something' >> /etc/privilegedFile"
The issue is that it's your shell that handles redirection; it's trying to open the file with your permissions not those of the process you're running under sudo.
Use something like this, perhaps:
sudo sh -c "echo 'something' >> /etc/privilegedFile"
The issue is that it's your shell that handles redirection; it's trying to open the file with your permissions not those of the process you're running under sudo.
Use something like this, perhaps:
sudo sh -c "echo 'something' >> /etc/privilegedFile"
sudo sh -c "echo 127.0.0.1 localhost >> /etc/hosts"
sudo sh -c "echo 127.0.0.1 localhost >> /etc/hosts"
sudo sh -c "echo 127.0.0.1 localhost >> /etc/hosts"
sudo sh -c "echo 127.0.0.1 localhost >> /etc/hosts"
Doing
sudo sh -c "echo >> somefile"
should work. The problem is that > and >> are handled by your shell, not by the "sudoed" command, so the permissions are your ones, not the ones of the user you are "sudoing" into.
Doing
sudo sh -c "echo >> somefile"
should work. The problem is that > and >> are handled by your shell, not by the "sudoed" command, so the permissions are your ones, not the ones of the user you are "sudoing" into.
Doing
sudo sh -c "echo >> somefile"
should work. The problem is that > and >> are handled by your shell, not by the "sudoed" command, so the permissions are your ones, not the ones of the user you are "sudoing" into.
Doing
sudo sh -c "echo >> somefile"
should work. The problem is that > and >> are handled by your shell, not by the "sudoed" command, so the permissions are your ones, not the ones of the user you are "sudoing" into.
I would note, for the curious, that you can also quote a heredoc (for large blocks):
sudo bash -c "cat <<EOIPFW >> /etc/ipfw.conf
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<plist version=\"1.0\">
<dict>
<key>Label</key>
<string>com.company.ipfw</string>
<key>Program</key>
<string>/sbin/ipfw</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/ipfw</string>
<string>-q</string>
<string>/etc/ipfw.conf</string>
</array>
<key>RunAtLoad</key>
<true></true>
</dict>
</plist>
EOIPFW"
I would note, for the curious, that you can also quote a heredoc (for large blocks):
sudo bash -c "cat <<EOIPFW >> /etc/ipfw.conf
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<plist version=\"1.0\">
<dict>
<key>Label</key>
<string>com.company.ipfw</string>
<key>Program</key>
<string>/sbin/ipfw</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/ipfw</string>
<string>-q</string>
<string>/etc/ipfw.conf</string>
</array>
<key>RunAtLoad</key>
<true></true>
</dict>
</plist>
EOIPFW"
In bash you can use tee
in combination with > /dev/null
to keep stdout clean.
echo "# comment" | sudo tee -a /etc/hosts > /dev/null
In bash you can use tee
in combination with > /dev/null
to keep stdout clean.
echo "# comment" | sudo tee -a /etc/hosts > /dev/null
Using Yoo's answer, put this in your ~/.bashrc
:
sudoe() {
[[ "$#" -ne 2 ]] && echo "Usage: sudoe <text> <file>" && return 1
echo "$1" | sudo tee --append "$2" > /dev/null
}
Now you can run sudoe 'deb blah # blah' /etc/apt/sources.list
Edit:
A more complete version which allows you to pipe input in or redirect from a file and includes a -a
switch to turn off appending (which is on by default):
sudoe() {
if ([[ "$1" == "-a" ]] || [[ "$1" == "--no-append" ]]); then
shift &>/dev/null || local failed=1
else
local append="--append"
fi
while [[ $failed -ne 1 ]]; do
if [[ -t 0 ]]; then
text="$1"; shift &>/dev/null || break
else
text="$(cat <&0)"
fi
[[ -z "$1" ]] && break
echo "$text" | sudo tee $append "$1" >/dev/null; return $?
done
echo "Usage: $0 [-a|--no-append] [text] <file>"; return 1
}
Using Yoo's answer, put this in your ~/.bashrc
:
sudoe() {
[[ "$#" -ne 2 ]] && echo "Usage: sudoe <text> <file>" && return 1
echo "$1" | sudo tee --append "$2" > /dev/null
}
Now you can run sudoe 'deb blah # blah' /etc/apt/sources.list
Edit:
A more complete version which allows you to pipe input in or redirect from a file and includes a -a
switch to turn off appending (which is on by default):
sudoe() {
if ([[ "$1" == "-a" ]] || [[ "$1" == "--no-append" ]]); then
shift &>/dev/null || local failed=1
else
local append="--append"
fi
while [[ $failed -ne 1 ]]; do
if [[ -t 0 ]]; then
text="$1"; shift &>/dev/null || break
else
text="$(cat <&0)"
fi
[[ -z "$1" ]] && break
echo "$text" | sudo tee $append "$1" >/dev/null; return $?
done
echo "Usage: $0 [-a|--no-append] [text] <file>"; return 1
}
You can also use sponge
from the moreutils
package and not need to redirect the output (i.e., no tee
noise to hide):
echo 'Add this line' | sudo sponge -a privfile
You can also use sponge
from the moreutils
package and not need to redirect the output (i.e., no tee
noise to hide):
echo 'Add this line' | sudo sponge -a privfile
Some user not know solution when using multiples lines.
sudo tee -a /path/file/to/create_with_text > /dev/null <<EOT
line 1
line 2
line 3
EOT
Some user not know solution when using multiples lines.
sudo tee -a /path/file/to/create_with_text > /dev/null <<EOT
line 1
line 2
line 3
EOT
By using sed -i with $ a , you can append text, containing both variables and special characters, after the last line.
For example, adding $NEW_HOST with $NEW_IP to /etc/hosts:
sudo sed -i "\$ a $NEW_IP\t\t$NEW_HOST.domain.local\t$NEW_HOST" /etc/hosts
sed options explained:
By using sed -i with $ a , you can append text, containing both variables and special characters, after the last line.
For example, adding $NEW_HOST with $NEW_IP to /etc/hosts:
sudo sed -i "\$ a $NEW_IP\t\t$NEW_HOST.domain.local\t$NEW_HOST" /etc/hosts
sed options explained:
echo 'Hello World' | (sudo tee -a /etc/apt/sources.list)
echo 'Hello World' | (sudo tee -a /etc/apt/sources.list)
How about:
echo text | sudo dd status=none of=privilegedfile
I want to change /proc/sys/net/ipv4/tcp_rmem.
I did:
sudo dd status=none of=/proc/sys/net/ipv4/tcp_rmem <<<"4096 131072 1024000"
eliminates the echo with a single line document
How about:
echo text | sudo dd status=none of=privilegedfile
I want to change /proc/sys/net/ipv4/tcp_rmem.
I did:
sudo dd status=none of=/proc/sys/net/ipv4/tcp_rmem <<<"4096 131072 1024000"
eliminates the echo with a single line document
This worked for me: original command
echo "export CATALINA_HOME="/opt/tomcat9"" >> /etc/environment
Working command
echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment
This worked for me: original command
echo "export CATALINA_HOME="/opt/tomcat9"" >> /etc/environment
Working command
echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment
Can you change the ownership of the file then change it back after using cat >>
to append?
sudo chown youruser /etc/hosts
sudo cat /downloaded/hostsadditions >> /etc/hosts
sudo chown root /etc/hosts
Something like this work for you?
Can you change the ownership of the file then change it back after using cat >>
to append?
sudo chown youruser /etc/hosts
sudo cat /downloaded/hostsadditions >> /etc/hosts
sudo chown root /etc/hosts
Something like this work for you?
Source: Stackoverflow.com