it-swarm-ru.tech

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

Мне предоставили доступ Sudo к одному из наших Linux-пакетов RedHat для разработки, и я, кажется, довольно часто нуждаюсь в перенаправлении вывода в местоположение, к которому у меня обычно нет доступа для записи.

Проблема в том, что этот надуманный пример не работает:

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

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

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

Как я могу заставить это работать?

760
Jonathan

Ваша команда не работает, потому что перенаправление выполняется вашей Командной консолью, у которой нет разрешения на запись в /root/test.out. Перенаправление вывода не выполняется Sudo.

Есть несколько решений:

  • Запустите Shell с Sudo и введите команду, используя опцию -c:

    Sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Создайте скрипт с вашими командами и запустите этот скрипт с помощью Sudo:

    #!/bin/sh
    ls -hal /root/ > /root/test.out
    

    Запустите Sudo ls.sh. Посмотрите answer Steve Bennett's /, если вы не хотите создавать временный файл.

  • Запустите командную консоль с помощью Sudo -s, затем запустите команды:

    [[email protected]]$ Sudo -s
    [[email protected]]# ls -hal /root/ > /root/test.out
    [[email protected]]# ^D
    [[email protected]]$
    
  • Используйте Sudo tee (если вам приходится много избегать при использовании опции -c):

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

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

Спасибо за это Jd , Адам Дж. Форстер и Джонатан за второе, третье и четвертое решения.

1068
Cristian Ciupitu

Кто-то здесь только что предложил sudoing tee:

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

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

89
Jonathan

Уловка, которую я понял сам, была

Sudo ls -hal /root/ | Sudo dd of=/root/test.out
70
rhlee

Проблема в том, что команда запускается под Sudo, а перенаправление запускается под вашим пользователем. Это делается Shell, и вы мало что можете с этим поделать.

Sudo command > /some/file.log
`-----v-----'`-------v-------'
   command       redirection

Обычные способы обойти это:

  • Оберните команды в скрипт, который вы вызываете под Sudo.

    Если команды и/или файл журнала изменяются, вы можете заставить скрипт Принимать их в качестве аргументов. Например:

    Sudo log_script command /log/file.txt
    
  • Вызовите Shell и передайте командную строку в качестве параметра с помощью -c

    Это особенно полезно для однократных составных команд .. Например.

    Sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
    
41
dsm

Еще одна вариация на тему:

Sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF

Или конечно:

echo 'ls -hal /root/ > /root/test.out' | Sudo bash

У них есть (крошечное) преимущество, заключающееся в том, что вам не нужно запоминать аргументы Sudo или sh/bash

19
Steve Bennett

Разъяснение, почему предпочтительным является вариант тройника

Предполагая, что у вас есть соответствующее разрешение на выполнение команды, которая создает выходные данные, если вы перенаправили выходные данные своей команды на 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, чтобы добавить add (например, >>) в целевой файл, а не перезаписать его (например, >).

18
jg3

Заставьте Sudo запустить Shell, вот так:

Sudo sh -c "echo foo > ~root/out"
15
Penfold

Я бы хотел решить эту проблему:

Если вам нужно написать/заменить файл:

echo "some text" | Sudo tee /path/to/file

Если вам нужно добавить в файл:

echo "some text" | Sudo tee -a /path/to/file
8
Nikola Petkanski

Как насчет написания сценария?

Имя файла: myscript

#!/bin/sh

/bin/ls -lah /root > /root/test.out

# end script

Затем используйте Sudo для запуска скрипта:

Sudo ./myscript
5
Jd

Я бы сделал это так:

Sudo su -c 'ls -hal /root/ > /root/test.out'
4
fardjad

Всякий раз, когда мне нужно сделать что-то подобное, я просто становлюсь пользователем root:

# Sudo -s
# ls -hal /root/ > /root/test.out
# exit

Это, вероятно, не лучший способ, но это работает.

3
Adam J. Forster

Не хочу бить мертвую лошадь, но здесь слишком много ответов, которые используют tee, что означает, что вы должны перенаправить stdout в /dev/null, если вы не хотите увидеть копию на экране. Более простое решение - просто использовать cat следующим образом:

Sudo ls -hal /root/ | Sudo bash -c "cat > /root/test.out"

Обратите внимание, как перенаправление помещается в кавычки, чтобы оно оценивалось командной оболочкой, запущенной Sudo вместо той, которая ее запускает.

3
haridsv

Это основано на ответе с участием 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 "[email protected]" ; do
    if [ ${arg#/dev/} != ${arg} ] ; then
        echo "Found dangerous argument ‘$arg’. Will exit."
        exit 2
    fi
done
Sudo tee "[email protected]" > /dev/null

Как показано вИСПОЛЬЗОВАНИИв коде, все, что вам нужно сделать, это направить вывод в этот скрипт, за которым следует желаемое доступное для суперпользователя имя файла, и оно автоматически запросит ваш пароль, если необходимо (так как включает в себя Sudo).

echo test | suwrite /root/test.txt

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

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

Он также имеет некоторую упрощенную защиту от записи на устройства /dev/, о которой упоминалось в одном из комментариев на этой странице.

2
jamadagni

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

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

cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out 

Нажмите ctrl + d :

chmod a+x myscript.sh
Sudo myscript.sh

Надеюсь, это поможет.

1
user15453
Sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  
0
user8648126