如何从命令行将文本附加到/etc/apt/sources.list?

我刚接触 Linux,刚刚开始学习 bash。我正在使用 Ubuntu 9.04,想要从命令行向/etc/apt/sources.list 添加存储库。基本上,我想这样做:

sudo echo "[some repository]" >> /etc/apt/sources.list

但是,即使在使用 sudo 时,也会出现这样的错误:

bash: /etc/apt/sources.list: Permission denied

如何避免此错误?

49306 次浏览
echo "[some repository]" | sudo tee -a /etc/apt/sources.list

The tee command is called as the superuser via sudo and the -a argument tells tee to append to the file instead of overwriting it.

Your original command failed, as the IO redirection with >> will be done as the regular user, only your echo was executed with sudo.

Calling a sudo subshell like

sudo sh -c 'echo "[some repository]" >> /etc/apt/sources.list'

works, too as pointed out by others.

One way to solve this is to do the redirection in a subshell:

sudo sh -c 'echo "[some repository]" >> /etc/apt/sources.list'

That way, the sh process is executed under sudo and therefore has the necessary privileges to open the redirected output to /etc/apt/sources.list.

The shell processes ">", "<", ">>" etc itself before launching commands. So the problem is that "sudo >> /etc/foo" tries to open /etc/foo for append before gaining privileges.

One way round this is to use sudo to launch another shell to do what you want, e.g.:

sudo sh -c 'echo "[some repository]" >> /etc/apt/sources.list'

Or alternatively:

echo "[some repository]" | sudo sh -c 'cat >> /etc/apt/sources.list'

A simpler approach may simply be to use sudo to launch an editor on the /etc/file :)

In Karmic, you can just use the add-apt-repository command, at least for PPAs.

For example:

sudo add-apt-repository ppa:docky

It's better to use a separate file in /etc/apt/sources.list.d rather than modifying /etc/apt/sources.list, as explained in this other answer. (Note that the file name MUST end in .list or it will be ignored.)

However, if you want to create it using echo the issue with permissions remains. You can use tee to create it like this:

echo '[some repository]' | sudo tee /etc/apt/sources.list.d/some-repository.list >/dev/null

or like this:

sudo tee /etc/apt/sources.list.d/some-repository.list >/dev/null <<EOF
[some repository]
EOF

Note that you don't need -a on the tee command (because you're not appending).

You can also create the file somewhere else and then copy it into place with:

sudo cp path/to/some-repository.list /etc/apt/sources.list.d/

If you were to switch to the root user the same command will work just fine. This is because sudo elevates the priveleges only for the [echo] command and does not elevate the right side of the output redirection.

sudo su
echo "[some repository]" >> /etc/apt/sources.list

If you do it this way be sure to exit from su so that you are not running unnecessary programs as root (superuser)

Following works for me

sudo echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" | sudo tee -a /etc/apt/sources.list.d/10gen.list

Here is solution without using piping, just simple in-place editing:

sudo ex +'$put = \"[some repository]\"' -cwq /etc/apt/sources.list

The ex is equivalent to vi -e.

first open or create the file you want to edit it by the following command

1- sudo nano file_name

2- edit the file after it opens

3- ctrl+x

4- press 'Y' to say yes

and you are done.

interesting, 1- remove the file with rm , 2 create the file again with touch, 3 use printf to print formatted, 4 pipe with tee to the file(THIS IS FOR DEBIAN) replace to your tastes and likes

sudo rm /etc/apt/sources.list && sudo touch /etc/apt/sources.list && sudo chmod +rwx /etc/apt/sources.list && sudo printf "deb http://deb.debian.org/debian buster main contrib non-free
deb-src http://deb.debian.org/debian buster main contrib non-free
deb http://deb.debian.org/debian-security/ buster/updates main contrib non-free
deb-src http://deb.debian.org/debian-security/ buster/updates main contrib non-free
deb http://deb.debian.org/debian buster-updates main contrib non-free
deb-src http://deb.debian.org/debian buster-updates main contrib non-free" | sudo tee -a /etc/apt/sources.list