sudo echo “щось” >> / etc / privilegedFile не працює


585

Це досить просте запитання, принаймні, схоже, як і слід, щодо дозволів sudo в Linux.

Буває дуже багато випадків, коли я просто хочу додати щось до /etc/hostsподібного файлу, але в кінцевому підсумку не в змозі, тому що обидва >і >>заборонено, навіть із root.

Чи є якийсь спосіб зробити цю роботу, не маючи до suабо sudo suвикорінюючи корінь?

Відповіді:


854

Використовуйте tee --appendабо tee -a.

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list

Обов’язково уникайте цитат всередині цитат.

Щоб уникнути друку даних на консоль, перенаправляйте вихід на / dev / null.

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list > /dev/null

Пам'ятайте про ( -a/ --append) прапор! Просто teeпрацює як >і замінить ваш файл. tee -aпрацює як >>і запише в кінці файлу.


3
Я абсолютно віддаю перевагу цьому. Це просто найпростіше (і це торкнулося мене трійника, що стане в нагоді і в інших сценаріях).
Йоахім Зауер

5
Я згоден. Здається, акуратніше, ніж починати новий ш, особливо, особливо з можливістю робити справи з оточенням тощо
Сем Брайтман

39
Одне важливе, що слід зазначити: НІКОЛИ не забувай -а! Уявіть собі, що echo 'tmpfs /tmp tmpfs defaults 0 0' | sudo tee /etc/fstabзробить
mic_e

21
В OS X це має бути tee -aзамість tee --append.
knite

26
Для тих, хто не розуміє, що сказав @mic_e: без-a--append прапора ( ) команда замінить весь файл заданим рядком, а не додасть його до кінця.
totymedli

313

Проблема полягає в тому, що оболонка робить перенаправлення виводу, а не sudo чи ехо, тому це робиться як ваш звичайний користувач.

Спробуйте наступний фрагмент коду:

sudo sh -c "echo 'something' >> /etc/privilegedfile"

Що таке "межі дозволу судо"? Це просто оболонка, яка аналізує оператор переадресації з більш високим пріоритетом, ніж команда з очевидних причин
Вінко Врсалович,

1
Залежно від ваших sh, ехо може інтерпретувати послідовності втечі, як \tусередині окремих цитат. Ви можете використати printf %s 'something'натомість.
Лрі

Використання трійника є більш популярним і більш сумісним з новими дистрибутивами.
Едуардо Б.

1
Це єдиний, який працює як - це команда SSH, яка може виконуватися на віддаленому вузлі.
Замок Дункана

Я погоджуюся з іншими публікаціями тут. Для цього використовується оболонка та лише оболонка, тому інша програма, як трійник, тут не потрібна. Так, я знаю, що трійник уже встановлений, але, можливо, не залежить від того, який мікро distro ви використовуєте, як голі кістки альпійські. Мені подобається, що у вас є варіант оболонки: sudo /bin/bash -c "echo 'fs.inotify.max_user_watches = 524288' > /etc/sysctl.d/60-golang-inotify.conf"наприклад.
Лігемер

35

Проблема полягає в тому, що саме ваша оболонка управляє перенаправленням; він намагається відкрити файл із вашими дозволами, а не тими з процесу, який ви виконуєте під sudo.

Можливо, використовуйте щось подібне, можливо:

sudo sh -c "echo 'something' >> /etc/privilegedFile"

@GordonSun це тому, що sudo(з міркувань безпеки) не поширює середовище на підпроцес. Ви можете використовувати sudo -Eдля обходу цього обмеження.
аріельф

1
@GordonSun так, це буде, я не розумію, чому ви постійно повторюєте це твердження! Якщо ви робите sudo sh -c "echo 'something' >> $FILENAME", подвійні лапки, це буде працювати - змінна заміна здійснюється з допомогою зовнішньої оболонки, а НЕ sudoed оболонки.
Nadav Har'El


13

Робимо

sudo sh -c "echo >> somefile"

повинні працювати. Проблема полягає в тому, що> і >> обробляються вашою оболонкою, а не командою "sudoed", тому дозволи - це ваші, а не ті користувачі, яких ви "вбираєте".


9

Зазначу, для допитливих, що ви можете також процитувати гередок (для великих блоків):

sudo bash -c "cat <<EOIPFW >> /etc/ipfw.conf
<?xml version=\"1.0\" encoding=\"UTF-8\"?>

<plist version=\"1.0\">
  <dict>
    <key>Label</key>
    <string>com.company.ipfw</string>
    <key>Program</key>
    <string>/sbin/ipfw</string>
    <key>ProgramArguments</key>
    <array>
      <string>/sbin/ipfw</string>
      <string>-q</string>
      <string>/etc/ipfw.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true></true>
  </dict>
</plist>
EOIPFW"

1
Це чудово працює, за винятком вбудованих цитат, можливо, знадобиться уникнути за допомогою \
N Jones

Цілком правильно @NJones! Я відредагую свою відповідь. (Однак зауважте, що не виконуючи це, знімає внутрішню, "але не призводить до відмови команди.)
msanford

8

В bash ви можете використовувати teeв поєднанні з, > /dev/nullщоб зберегти stdout в чистоті.

 echo "# comment" |  sudo tee -a /etc/hosts > /dev/null

4

За допомогою відповіді Yoo введіть це у свої ~/.bashrc:

sudoe() {
    [[ "$#" -ne 2 ]] && echo "Usage: sudoe <text> <file>" && return 1
    echo "$1" | sudo tee --append "$2" > /dev/null
}

Тепер ви можете бігти sudoe 'deb blah # blah' /etc/apt/sources.list


Редагувати:

Більш повна версія, яка дозволяє вводити або перенаправляти файли з файлу і включає -aперемикач, щоб вимкнути додавання (який за замовчуванням увімкнено):

sudoe() {
  if ([[ "$1" == "-a" ]] || [[ "$1" == "--no-append" ]]); then
    shift &>/dev/null || local failed=1
  else
    local append="--append"
  fi

  while [[ $failed -ne 1 ]]; do
    if [[ -t 0 ]]; then
      text="$1"; shift &>/dev/null || break
    else
      text="$(cat <&0)"
    fi

    [[ -z "$1" ]] && break
    echo "$text" | sudo tee $append "$1" >/dev/null; return $?
  done

  echo "Usage: $0 [-a|--no-append] [text] <file>"; return 1
}

2

Ви також можете використовувати spongeз moreutilsпакету, і не потрібно перенаправляти вихід (тобто немає teeшуму для приховування):

echo 'Add this line' | sudo sponge -a privfile

0

За допомогою sed -i з $ a , ви можете додати текст, що містить як змінні, так і спеціальні символи, після останнього рядка.

Наприклад, додавши $ NEW_HOST з $ NEW_IP до / etc / hosts:

sudo sed -i "\$ a $NEW_IP\t\t$NEW_HOST.domain.local\t$NEW_HOST" /etc/hosts

Пояснено варіанти sed:

  • за місцем
  • $ за останній рядок
  • а для додавання


0

Як щодо:
ехо текст | sudo dd status = none of = privilegedfile
Я хочу змінити / proc / sys / net / ipv4 / tcp_rmem.
Я зробив:
sudo dd status = none of = / proc / sys / net / ipv4 / tcp_rmem <<< "4096 131072 1024000"
усуває відлуння за допомогою одного рядкового документа


1
Будь ласка, знайдіть хвилину, щоб прочитати допомогу з редагування у довідковому центрі . Форматування на переповнення стека відрізняється від інших сайтів.
Дхарман

-1

Це працювало для мене: оригінальна команда

echo "export CATALINA_HOME="/opt/tomcat9"" >> /etc/environment

Робоча команда

echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment

1
Повинно бути tee -a. Просто teeперезапишемо файл!
codeforester

-6

Чи можете ви змінити право власності на файл, а потім змінити його назад після використання cat >>для додавання?

sudo chown youruser /etc/hosts  
sudo cat /downloaded/hostsadditions >> /etc/hosts  
sudo chown root /etc/hosts  

Щось подібне до цього твору?


4
Чуун - це руйнівна команда, яку потрібно використовувати. Якщо менеджер конфігурацій використовував це для оновлення / etc / hosts, раптом / etc / hosts належить користувачеві config, а не root. що потенційно призводить до інших процесів, які не мають доступу до / etc / hosts. Вся суть у тому, щоб уникнути того, щоб щось увійшло в корінь, а також через судори можна також накласти більше обмежень.
Давид
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.