Как использовать sudo для перенаправления вывода в местоположение, в которое у меня нет разрешения на запись?
Мне был предоставлен доступ sudo к одному из наших Linux-пакетов RedHat для разработки, и я, похоже, довольно часто нуждаюсь в перенаправлении вывода в местоположение, к которому у меня обычно нет прав на запись.
Проблема в том, что этот надуманный пример не работает:
sudo ls -hal /root/ > /root/test.out
Я просто получаю ответ:
-bash: /root/test.out: Permission denied
Как я могу заставить это работать?
15 ответов
Ваша команда не работает, потому что перенаправление выполняется вашей оболочкой, у которой нет разрешения на запись в /root/test.out
, Перенаправление вывода не выполняется sudo.
Есть несколько решений:
Запустите оболочку с помощью sudo и введите команду, используя команду
-c
опция:sudo sh -c 'ls -hal /root/ > /root/test.out'
Создайте скрипт с вашими командами и запустите этот скрипт с помощью sudo:
#!/bin/sh ls -hal /root/ > /root/test.out
Бежать
sudo ls.sh
, Посмотрите ответ Стива Беннетта, если вы не хотите создавать временный файл.Запустить оболочку с
sudo -s
затем запустите ваши команды:[nobody@so]$ sudo -s [root@so]# ls -hal /root/ > /root/test.out [root@so]# ^D [nobody@so]$
использование
sudo tee
(если вам приходится много убегать при использовании-c
опция):sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
Перенаправление на
/dev/null
необходим, чтобы остановить вывод на экран. Добавить вместо перезаписи выходной файл (>>
), используйтеtee -a
или жеtee --append
(последний характерен для GNU coreutils).
Благодарю Jd, Adam J. Forster и Johnathan за второе, третье и четвертое решения.
Кто-то здесь только что предложил sudoing tee:
sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
Это также может быть использовано для перенаправления любой команды в каталог, к которому у вас нет доступа. Это работает, потому что программа tee фактически является программой "echo to a file", и перенаправление на /dev/null - это остановка ее вывода на экран, чтобы сохранить ее такой же, как в оригинальном надуманном примере выше.
Уловка, которую я понял сам, была
sudo ls -hal /root/ | sudo dd of=/root/test.out
Проблема в том, что команда запускается под sudo
, но перенаправление запускается под вашим пользователем. Это делается оболочкой, и вы мало что можете с этим поделать.
sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
Обычные способы обойти это:
Оберните команды в скрипт, который вы вызываете под sudo.
Если команды и / или файл журнала изменяются, вы можете заставить скрипт принимать их в качестве аргументов. Например:
sudo log_script command /log/file.txt
Вызовите оболочку и передайте командную строку в качестве параметра с
-c
Это особенно полезно для составных команд. Например:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
Еще одна вариация на тему:
sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF
Или конечно:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
У них есть (крошечное) преимущество в том, что вам не нужно запоминать аргументы sudo
или же sh
/bash
Разъяснение, почему предпочтительным является вариант тройника
Предполагая, что у вас есть соответствующее разрешение на выполнение команды, которая создает выходные данные, если вы перенаправили выходные данные своей команды на tee, вам нужно лишь повысить привилегии tee с помощью sudo и направить tee для записи (или добавления) в рассматриваемый файл.
в примере, приведенном в вопросе, это будет означать:
ls -hal /root/ | sudo tee /root/test.out
для пары более практических примеров:
# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts
# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4
В каждом из этих примеров вы берете выходные данные непривилегированной команды и записываете в файл, который обычно доступен для записи только пользователю root, что является источником вашего вопроса.
Это хорошая идея, потому что команда, которая генерирует вывод, не выполняется с повышенными привилегиями. Это не имеет значения здесь с echo
но когда исходная команда является сценарием, которому вы не полностью доверяете, это очень важно.
Обратите внимание, что вы можете использовать опцию -a для добавления и добавления (например, >>
) в целевой файл, а не перезаписывать его (например, >
).
Заставьте sudo запустить оболочку, вот так:
sudo sh -c "echo foo > ~root/out"
Я бы хотел решить эту проблему:
Если вам нужно написать / заменить файл:
echo "some text" | sudo tee /path/to/file
Если вам нужно добавить в файл:
echo "some text" | sudo tee -a /path/to/file
Не хочу бить мертвую лошадь, но здесь слишком много ответов, которые используют tee
, что означает, что вы должны перенаправить stdout
в /dev/null
если вы не хотите увидеть копию на экране. Более простое решение - просто использовать cat
как это:
sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
Обратите внимание, как перенаправление помещается в кавычки, чтобы оно оценивалось оболочкой, запущенной sudo
вместо того, чтобы запустить его.
Как насчет написания сценария?
Имя файла: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Затем используйте sudo для запуска скрипта:
sudo ./myscript
Всякий раз, когда мне нужно сделать что-то подобное, я просто становлюсь пользователем root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
Это, вероятно, не лучший способ, но это работает.
Я бы сделал это так:
sudo su -c 'ls -hal /root/ > /root/test.out'
Вот расширение ответа с участием тройника. Чтобы упростить задачу, вам может потребоваться сделать небольшой скрипт (я называю его suwrite или вы можете назвать его sutee) и поместить его в /usr/local/bin/ с разрешением +x:
#! /bin/sh
sudo tee $@ > /dev/null
Теперь все, что вам нужно сделать, это направить вывод в этот скрипт, за которым следует желаемое доступное для суперпользователя имя файла, и оно автоматически запросит ваш пароль, если это необходимо (поскольку оно включает sudo).
echo test | suwrite /root/test.txt
Обратите внимание, что, поскольку это простая оболочка для tee, она также примет опцию -e (или любую другую), поэтому для добавления к желаемому файлу вы просто передаете -a:
echo test | suwrite -a /root/test.txt
sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017
Может быть, вам был предоставлен доступ sudo только к некоторым программам / путям? Тогда нет способа делать то, что вы хотите. (если вы не взломаете это как-то)
Если это не так, то, возможно, вы можете написать скрипт bash:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Нажмите Ctrl + D:
chmod a+x myscript.sh
sudo myscript.sh
Надеюсь, это поможет.