Когда вы пытаетесь изменить файл без разрешения на запись, вы получаете сообщение об ошибке:
> touch /tmp/foo && sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Sudoing не помогает, потому что он запускает команду от имени пользователя root, но оболочка обрабатывает перенаправление stdout и в любом случае открывает файл как вы:
> sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Существует ли простой способ перенаправить стандартный вывод в файл, на который у вас нет разрешения на запись, кроме открытия оболочки в качестве пользователя root и манипулирования этим способом?
> sudo su
# echo test > /tmp/foo
shell
permissions
io-redirection
sudo
io
Майкл Mrozek
источник
источник
chown
менял владельца; это был просто примерОтветы:
Да, используя
tee
. Такecho test > /tmp/foo
становитсяВы также можете добавить (
>>
)источник
echo test | sudo tee /tmp/foo > /dev/null
Заменить содержимое файла с выводом
echo
(как>
оператор перенаправления оболочки).Чтобы записать в файл (в начале, хотя вы можете использовать
seek
для вывода с разными смещениями) без усечения (например,1<>
оператор оболочки Bourne):Чтобы добавить в файл (вроде
>>
), с помощью GNUdd
:Смотрите также GNU
dd
,conv=excl
чтобы избежать путаницы в существующем файле (например,set -o noclobber
в оболочках POSIX), иconv=nocreat
наоборот (только обновить существующий файл).источник
echo test | sudo tee /tmp/foo >/dev/null
чтобы отказаться от вывода.dd
это ненадежно, если только вы не используете неясные опции только для GNUiflag=fullblock oflag=fullblock
, которые убирают элегантность этого ответа. Я буду придерживатьсяtee
.dd
может быть довольно опасным (если не сказать: разрушительным), если была допущена лишь небольшая ошибка. Поэтому для новых пользователей я бы рекомендовал этотtee
метод, чтобы быть на безопасном берегу.dd of=file
одного (безcount
/skip
...), это надежно.iflag=fullblock
не нужен, потому что здесьdd
пишет на выходе, что он прочитал на входе. Неважно, если это не были полные блоки.tee
Возможно, это лучший выбор, но в зависимости от вашей ситуации может быть достаточно чего-то подобного:источник
eval
вместо простойsh -c
; -i, который изменит ваш рабочий каталог; запуск всей команды от имени root, что может изменить ее поведение или может привести к ненужному риску. почему это когда-либо получило голос?Хотя я согласен, это
| sudo tee
канонический способ, иногда sed (здесь предполагается GNUsed
) может работать:-i
изменяет файл на месте.1i
означает вставить перед строкой 1.$a
означает добавить после последней строки.Или скопируйте в xclipboard:
источник
sed -i
самом деле файл не изменяется на месте - он создает временный файл и переименовывает его при выходе. Таким образом, вы не сможете сделать что-то похожееtail -f ...
на исходный файл и увидеть результат, используяsed -i ...
во время работы конвейера-i creates a new file of same name
или есть что-то более компактное? Я думаю, мне нравитсяin place
, потому что это объясняетi
. Манн-страница gnu-sed также называет это на месте, и длинный флаг есть--in-place
.Я долго обдумывал идеи подобной проблемы и придумал следующие решения:
sudo uncat
гдеuncat
- программа, которая читает стандартный ввод и записывает его в файл, указанный в командной строке, но я еще не написалuncat
.sudocat
вариант,sudoedit
который я еще не написал, который делает уборщикsudo cat
илиsudo uncat
.или этот маленький трюк использования
sudoedit
с редактором, который является сценарием оболочкикоторый может быть вызван как
|sudo ./uncat file
или,| EDITOR=./uncat sudoedit
но имеет интересные побочные эффекты.источник
cat
принимает список файлов для кон кошки inate, поэтому UNCAT должен взять список файлов для ООН мошенника кота inate к. Пришлось бы использовать магию, чтобы решить, сколько положить в каждый файл. Альтернативное название включаетdog
,to-file
,redirect
.uncat
когда у меня естьtee
.tee
него есть тривиальный недостаток, заключающийся в том, что он записывает свой стандартный ввод в свой стандартный вывод - который тривиально смягчается путем перенаправления стандартного вывода в/dev/null
. Другие альтернативы включаютdd of=/tmp/foo
(упомянутый в другом ответе), который записывает информацию о состоянии в stderr, иcp /dev/stdin /tmp/foo
.Используйте губку из пакета moreutils. Преимущество в том, что он не пишет в стандартный вывод.
Используйте параметр -a, чтобы добавить файл вместо перезаписи.
источник
/dev/null
если это было проблемойОшибка происходит от порядка, в котором оболочка делает вещи.
Перенаправление обрабатывается еще до запуска оболочки и
sudo
, следовательно, выполняется с разрешениями пользователя, с которым вы в данный момент работаете. Поскольку у вас нет разрешения на запись для создания / усечения цели перенаправления, вы получаете сообщениеpermission denied
об ошибке из оболочки.Решение состоит в том, чтобы гарантировать, что выходной файл будет создан под идентификатором, данным вам
sudo
, например, с помощьюtee
:источник