Linux

Как использовать sudo для перенаправления вывода, если у меня нет разрешения на запись

Мне дали доступ sudo на одном из наших рабочих компьютеров RedHat linux, и я часто сталкиваюсь с необходимостью перенаправить вывод в место, к которому у меня обычно нет доступа на запись. Проблема в том, что этот надуманный пример не работает:

sudo ls -hal /root/ > /root/test.out

 Я просто получаю ответ:

-bash: /root/test.out: Permission denied

 

Как заставить это работать?

 

Ответ 1

Ваша команда не работает, потому что перенаправление выполняется вашей оболочкой, у которой нет разрешения на запись в /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 (если вам нужно часто использовать escape вместе с опцией -c):

sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null

Перенаправление на /dev/null необходимо, чтобы остановить вывод tee на экран. Чтобы добавить вместо перезаписи выходной файл ( >>), используйте tee –a или tee --append (последний специфичен для GNU coreutils).

 

Ответ 2

При использовании sudoing tee:

sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null

Это также можно использовать для перенаправления любой команды в каталог, к которому у вас нет доступа. Это работает, потому что программа tee фактически является программой «эхо в файл», а перенаправление на /dev/null должно остановить ее вывод на экран, чтобы она оставалась такой же, как в исходном надуманном примере выше.

 

Ответ 3

Проблема в том, что команда выполняется под 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"

 

Ответ 4

Если у вас есть соответствующие права на выполнение команды, создающей вывод, то при передаче вывода команды в tee вам нужно только повысить права tee с помощью sudo и направить tee на запись (или добавление) в соответствующий файл.

 В примере, приведенном в вопросе, это означает:

ls -hal /root/ | sudo tee /root/test.out

 Еще несколько практических примеров:

# уничтожить один источник

echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts

# настройте eth4 на загрузку, установите IP и маску сети (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 для tee, чтобы добавлять (как >>) к целевому файлу, а не перезаписывать его (как >).

 

Ответ 5

Это основано на ответе с участием tee. Чтобы упростить задачу, я написал небольшой скрипт (я назвал его suwrite) и поместил его в /usr/local/bin/ с разрешением +x:

#! /bin/sh

if [ $# = 0 ] ; then

    echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2

    exit 1

fi

for arg in "$@" ; do

    if [ ${arg#/dev/} != ${arg} ] ; then

        echo "Найден опасный аргумент ‘$arg’. Will exit."

        exit 2

    fi

done

sudo tee "$@" > /dev/null

 Как показано в USAGE в коде, все, что вам нужно сделать, — это передать вывод в этот скрипт, а затем указать желаемое имя файла с доступом суперпользователя, и он автоматически запросит ваш пароль, если это необходимо (поскольку он включает sudo).

echo test | suwrite /root/test.txt

 Обратите внимание, что, поскольку это простая обертка для tee, она также принимает опцию tee -a для добавления и поддерживает одновременную запись в несколько файлов.

echo test2 | suwrite -a /root/test.txt

echo test-multi | suwrite /root/test-a.txt /root/test-b.txt

 

Он также имеет упрощенную защиту от записи на устройства /dev/.

 

Ответ 6

Может быть, вам дали доступ sudo только к некоторым программам/путям? Тогда нет возможности сделать то, что вы хотите (если только вы не взломаете его каким-то образом).

Если это не так, то, возможно, вы можете написать bash-скрипт:

cat > myscript.sh

#!/bin/sh

ls -hal /root/ > /root/test.out 

chmod a+x myscript.sh

sudo myscript.sh

 

Схожие статьи

Linux

Файловая система с распределенным хранилищем. Есть ли готовый к использованию продукт?

Для чего нужны открытые CAD программы для Linux, какие они бывают
Linux

Для чего нужны открытые CAD программы для Linux, какие они бывают

Linux

Как обеспечить правильное резервное копирование нескольких серверов на базе Linux?

Linux

Есть ли способ для некорневых процессов привязаться к «привилегированным» портам в Linux?

×