cURL в bash-скрипте читает $HOME как /root/

Вопрос или проблема

ОС, о которой идет речь, – Fedora 40.

Я хотел бы создать директорию и скачать в нее файл, поэтому я написал этот простой скрипт

#!/bin/bash

set -eu -o pipefail 

sudo -n true
test $? -eq 0 || exit 1

curlpackages="$HOME/curl-packages"
mkdir -p $curlpackages
curl --output-dir $curlpackages -JLO <someaddress>

Я ожидал, что директория и файл будут в /home/myname/, но вместо этого я получаю /root/. Связано ли это с тем, что я запускаю это с sudo? Если да, могу ли я использовать другую переменную вместо $HOME, чтобы указать на свою домашнюю папку вместо root?

Связано ли это с тем, что я запускаю это с sudo?

Да

Если да, могу ли я использовать другую переменную вместо $HOME, чтобы указать на свою домашнюю папку вместо root?

Почему бы не поместить вашу команду sudo в скрипт – только для тех команд, которые необходимо выполнять от имени root, вместо того чтобы запускать весь скрипт от имени root:

Обратите внимание, что, например, sudo echo $HOME выведет вашу ожидаемую домашнюю директорию – потому что расширение этой переменной происходит до выполнения команды.

Вы можете использовать $SUDO_USER

SUDO_USER
Устанавливается в имя входа пользователя, который вызвал sudo.

#!/bin/bash

set -eu -o pipefail 

sudo -n true
test $? -eq 0 || exit 1

userhome=$(eval echo "~$SUDO_USER")
curlpackages="$userhome/curl-packages"
mkdir -p "$curlpackages"
curl --output-dir "$curlpackages" -JLO <someaddress>

Руководство по Sudo

Идентификация пользователя в Bash-скрипте, вызванном с помощью sudo

SUDO_USER задокументирован в man sudo

Вам нужно будет указать вашего пользователя так, так как вы root:
curlpackages="/home/<yourUser>/curl-packages"

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

  • Вы стали root, например, с помощью: sudo -i или su?
  • Если да, тогда exit и запустите скрипт так: sudo bash script.bash
  • Тогда вам не нужно будет ничего менять
  • Проверка кода выхода не требуется, sudo -n true не позволит скрипту выполняться пользователям без разрешений на sudo
  • Вы проверяете одно и то же дважды

Вот что я имею в виду, небольшое улучшение вашего кода:

#!/bin/bash

set -eu -o pipefail 

sudo -n true

curlpackages="$HOME/curl-packages"
mkdir -p $curlpackages
curl --output-dir $curlpackages -JLO <someaddress>

Ответ или решение

Конечно, давайте разберем вашу ситуацию более детально.

Ваша проблема заключается в том, что при выполнении скрипта с использованием sudo, переменная окружения $HOME ссылается на домашний каталог пользователя root (то есть /root/), а не на домашний каталог вашего текущего пользователя. Это поведение является нормальным при использовании sudo, так как оно запускает команды от имени пользователя root.

Решение:

Чтобы решить эту проблему, вы можете использовать переменную окружения $SUDO_USER, которая содержит имя пользователя, запустившего команду sudo. Это дает вам возможность получить правильный домашний каталог для выполнения вашего скрипта.

Вот так ваш скрипт может выглядеть с использованием $SUDO_USER:

#!/bin/bash

set -eu -o pipefail 

# Проверяем, есть ли у пользователя права на sudo
sudo -n true

# Получаем домашний каталог пользователя, который запустил скрипт через sudo
userhome=$(eval echo "~$SUDO_USER")

curlpackages="$userhome/curl-packages"
mkdir -p "$curlpackages"
curl --output-dir "$curlpackages" -JLO <someaddress>

Объяснение кода:

  1. Получение домашнего каталога: Используя eval echo "~$SUDO_USER", мы генерируем путь к домашнему каталогу пользователя, который инициировал команду sudo, благодаря чему у вас будет правильный каталог для загрузки файлов.

  2. Создание директории: После получения пути мы создаем каталог curl-packages в нужном месте, если он ещё не существует.

  3. Скачивание файла: В конце скрипта мы используем curl для загрузки файла в этот каталог.

Альтернативный подход:

Если вы не хотите использовать $SUDO_USER, вы можете указать домашний каталог явно в вашем скрипте, заменив $HOME на /home/<ваше_имя_пользователя>/. Но использование $SUDO_USER делает ваш скрипт более универсальным и адаптируемым для различных пользователей.

Рекомендации:

  1. Рассмотрите возможность запуска самого скрипта через sudo, без необходимости sudo внутри него для всех команд, если они не требуют прав администратора.
  2. Проверка прав доступа с помощью sudo -n true является избыточной, поскольку, если у пользователя нет прав на использование sudo, скрипт просто не выполнится.

Таким образом, предложенное решение позволяет решить проблему с неверным домашним каталогом при использовании sudo, при этом сохраняя вашу работу организованной и понятной.

Оцените материал
Добавить комментарий

Капча загружается...