ZaLinux.ru

Как использовать echo вместе с sudo

Команда echo используется для вывода передаваемой ей строки. По умолчанию показывает строку на экране, но при перенаправлении вывода, например с помощью >> или > может, соответственно, дописывать строку в файл или полностью перезаписывать его этой строкой.

Но что если нам нужно дописать строку в файл требующих повышенных привилегий примерно следующей командой:

sudo echo "что-нибудь" >> /etc/файл_требующий_повышенных_привилегий

Это довольно распространённая ситуация, когда нужно добавить что-то в файл /etc/hosts или подобный. Кажется, что это довольно простая конструкция: перед echo добавлена sudo, которая позволяет выполнять команды от других пользователей, в данном случае от root.

То есть команда должна выполняться с повышенными привилегиями, что должно дать права на запись в файл. Но в этом случае ни > , ни >> не получится использовать, в том числе как root. И будет выведена ошибка вида:

bash: /etc/file: Отказано в доступе

Нам на помощь может прийти команда tee. Используйте её с опциями --append или -a — это важно, без этих опций файл будет полностью перезаписан. Пример:

echo 'новая строка' | sudo tee --append /etc/apt/sources.list

Приведённая команда допишет новую строку в существующий файл.

Но особенность команды tee в том, что она не только допишет файл, но ещё и выведет добавленную строку в консоль. Если вы не хотите, чтобы данные вновь возвращались в консоль, то сделайте редирект вывода на /dev/null.

Пример:

echo 'новая строка' | sudo tee --append /etc/apt/sources.list > /dev/null

Это будет работать аналогичным образом, но на экран не будет выведена 'новая строка'.

Ещё один вариант использования echo для записи или добавления в файл от имени администратора:

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

У этого варианта есть своя специфика. Во-первых, команда echo работает от рута, следовательно, оказывается в его рабочем окружении. В большинстве ситуаций это неважно, но если вы хотите использовать эту команду с переменными среды $EVN_VARIBLE (например, $PATH или $USER), то вы можете получить неожиданный результат — будет взята переменная среды пользователя root, а не вашего текущего пользователя.

Ещё в команде используются и одинарные и двойные кавычки, это означает, что если в строке, которую вы добавляете в файл, также есть кавычки, то они должны быть экранированы обратными слэшами.

Кстати, просто к слову, если вам нужно дописать большие блоки, то вы можете использовать команду cat и heredoc:

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"

И ещё один пример для тех, кто любит обстоятельно настраивать свою систему и делать пользовательский тюнинг, в том числе с добавлением своих собственных комплексных команд. Добавьте в файл ~/.bashrc следующую функцию:

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
}

Теперь вы сможете использовать новую команду sudoe следующим образом:

sudoe 'новая строка' /etc/apt/sources.list

По умолчанию установлена опция --append — она означает дописывать существующий файл. Если вы хотите перезаписать, то есть удалить текущее содержимое и записать только новую строку, то используйте с этой командой опции -a или --no-append.

И ещё парочка экзотических методов. В пакете moreutils есть утилита sponge, она позволяет дописать строку в привилегированный файл без необходимости делать редирект вывода (не нужно прятать шум от tee):

echo 'Добавить эту строку' | sudo sponge -a /etc/привилегированный_файл

И ещё один способ это использование sed -i с $ a. Вы можете добавить строку командой следующего вида:

sudo sed -i "\$ a Строка для добавления" /etc/привилегированный_файл

Объяснение опций sed:

  • -i - в месте
  • $ - последняя строка
  • a - добавить

С помощью sed можно добавлять весьма сложные строки, содержащие переменные и специальные символы. Допустим нам нужно добавить $NEW_HOST с $NEW_IP в /etc/hosts:

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

Рекомендуемые статьи:

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *