Как использовать sudo для перенаправления вывода в место, где у меня нет разрешения на запись?
мне был предоставлен доступ sudo на одном из наших ящиков RedHat linux для разработки, и я, похоже, довольно часто нуждаюсь в перенаправлении вывода в место, к которому у меня обычно нет доступа для записи.
беда в том, что этот надуманный пример не работает:
sudo ls -hal /root/ > /root/test.out
Я просто получаю ответ:
-bash: /root/test.out: Permission denied
Как я могу заставить это работать?
15 ответов:
ваша команда не работает, потому что перенаправление выполняется вашей оболочкой, которая не имеет разрешения на запись в
/root/test.out
. Перенаправление вывода не в исполнении sudo.есть несколько решений:
запустите оболочку с sudo и дайте ему команду с помощью :
sudo sh -c 'ls -hal /root/ > /root/test.out'
создайте скрипт с вашими командами и запустите этот скрипт с помощью судо:
#!/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
(если вы должны бежать много при использовании ):sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
перенаправление
/dev/null
это тройник вывода на экран. К добавить вместо перезаписи выходного файла (>>
), используйтеtee -a
илиtee --append
(последний специфичен для GNU coreutils).спасибо Jd,Адам Дж. Форстер и Джонатан для второго, третьего и четвертого решения.
кто-то здесь только что предложил sudoing tee:
sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
Это также может быть использовано для перенаправления любой команды в каталог, к которому у вас нет доступа. Это работает, потому что программа tee является эффективной программой "эхо в файл", и перенаправление на /dev/null должно остановить его также вывод на экран, чтобы сохранить его таким же, как и исходный надуманный пример выше.
проблема в том, что команда запускается под
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 и direct 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 вариант тройник, чтобы добавить добавить (например
>>
) в целевой файл, а не перезаписать его (например,>
).
способ, которым я бы пошел по этому вопросу:
Если вам нужно написать/заменить файл:
echo "some text" | sudo tee /path/to/file
Если вам нужно добавить в файл:
echo "some text" | sudo tee -a /path/to/file
Как насчет написания скрипта?
имя файла: 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
Это, наверное, не лучший способ, но он работает.
вот расширение ответа с участием тройника. Чтобы упростить работу, вы можете сделать небольшой скрипт (я называю его suwrite или вы можете назвать его sutee) и поместить его в /usr / local/bin/ с разрешением +x:
#! /bin/sh sudo tee $@ > /dev/null
Теперь все, что вам нужно сделать, это передать вывод в этот скрипт с последующим желаемым именем файла, доступным для суперпользователя, и он автоматически предложит вам ввести пароль, если это необходимо (поскольку он включает sudo).
echo test | suwrite /root/test.txt
обратите внимание, что, так как это простая обертка для tee, он также будет принимать tee's-a (или любой другой) вариант, чтобы добавить к нужному файлу вы просто передаете -a:
echo test | suwrite -a /root/test.txt
не хочу бить мертвую лошадь, но здесь слишком много ответов, которые используют
tee
, что означает, что вы должны перенаправитьstdout
до/dev/null
Если вы не хотите видеть копию на экране. Более простое решение-просто использоватьcat
такой:sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
обратите внимание, как перенаправление помещается в кавычки, чтобы оно оценивалось оболочкой, запущенной
sudo
вместо того, чтобы запустить его.
может быть, вам был предоставлен доступ sudo только к некоторым программам / путям? Тогда нет никакого способа сделать то, что вы хотите. (если вы не будете взломать его как-то)
Если это не так, то, возможно, вы можете написать сценарий bash:
cat > myscript.sh #!/bin/sh ls -hal /root/ > /root/test.out
пресс ctrl + d:
chmod a+x myscript.sh sudo myscript.sh
надеюсь, что это поможет.