Запуск скриптов из другого каталога

11

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

Это хорошая практика для запуска скриптов (BASH, Perl и т. Д.) Из другого каталога? Будут ли они обычно находить все необходимое для правильной работы?

Если да, то как лучше всего запустить «дальний» скрипт? Это

. /path/to/script

или

sh /path/to/script

и как использовать sudoв таких случаях? Это, например, не работает:

sudo . /path/to/script
Десмонд Хьюм
источник
Имейте в виду, что . /path/to/script источники сценария! Вам не нужен период вообще, если вы просто хотите запустить его.
gniourf_gniourf

Ответы:

14

sh / path / to / script создаст новую оболочку и запустит скрипт независимо от вашей текущей оболочки. Команда source(.) Вызовет все команды в сценарии в текущей оболочке. Если скрипт вызовет, exitнапример, то вы потеряете текущую оболочку. Из-за этого обычно безопаснее вызывать скрипты в отдельной оболочке с помощью sh или выполнять их как двоичные файлы, используя полный (начиная с /) или относительный путь (./). Если они называются двоичными файлами, они будут выполняться с указанным интерпретатором (например, #! / Bin / bash).

Что касается знания того, найдет ли сценарий нужные ему файлы, то нет хорошего ответа, кроме как посмотреть на сценарий и посмотреть, что он делает. Как вариант, вы всегда можете перейти к папке скрипта в подпроцессе, не выходя из текущей папки:

$(cd /wherever/ ; sh script.sh)
Ярослав Рахматуллин
источник
3
Вы имеете в виду (cd /wherever/ ; sh script.sh)? Почему у вас $впереди?
G-Man говорит: «Восстановите Монику»
7

Вы определенно можете сделать это (с изменениями, упомянутыми другими, например sudo sh /pathto/script.shили ./script.sh). Тем не менее, я делаю одну из нескольких вещей, чтобы запустить их в масштабе всей системы, чтобы не беспокоиться о директориях и избавить меня от лишней лишней печати.

1) Симлинк на /usr/bin

ln -s /home/username/Scripts/name.sh /usr/bin/name

(убедитесь, что там нет перекрывающихся имен, потому что вы, очевидно, переопределите его.) Это также позволяет мне хранить их в моих папках для разработки, чтобы я мог настроить их при необходимости.

2) Добавьте каталог Scripts на ваш путь (используя .bash_profile - или любой другой .profile, который есть в вашей оболочке)

PATH=/path/to/scripts/:$PATH

3) Создание псевдонима находится в .bash_profile в ~/.bash_profileнадстройке что - то вроде:

alias l="ls -l"

Как вы можете сказать, синтаксис просто псевдоним, цифры, которые вы хотите действовать как команда, команда. Таким образом, если вы введете «l» в любом месте терминала, то получится, ls -l если вы хотите sudo, просто alias sl="sudo ls -l"отметьте для себя l vs sl (в качестве бесполезного примера).

В любом случае, вы можете просто напечатать sudo nameofscriptи быть на своем пути. Не нужно связываться с ./ или. или sh и т. д. Просто отметьте их как исполняемые в первую очередь: D

nerdwaller
источник
Я очень рекомендую вариант 2.
Бернхард
Почему? Это лучшая практика или просто вкус?
Серхио
3

Я обычно делаю так, как ты говоришь

sh /path/to/script

И запустить его от имени root / superuser

sudo sh /path/to/script

Ваш текущий каталог имеет значение, только если сценарии предполагают, что вы находитесь в той же папке, что и он. Я бы предположил, что большинство сценариев этого не делают, и вы сохраните его, как показано выше.

Болл
источник
не будет работать, если в файле / etc / sudoers
задан secure_path
3

Я обычно храню свои сценарии в ( /usr/local/binили /usr/local/sbin/(если сценарию требуются права суперпользователя), где, в соответствии со стандартом иерархии файловой системы (FHS), они принадлежат.

Все, что вам нужно сделать, это убедиться, что эти два каталога добавлены в ваш PATH. Вы можете сделать это, отредактировав свой $HOME/.bashrcфайл и добавив следующую строку:

export PATH=$PATH:/usr/local/sbin:/usr/local/bin

Если вы хотите иметь возможность выполнять скрипт от имени пользователя root sudo, вам нужно добавить эти каталоги в переменную secure_pathвашего /etc/sudoers.

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

Редактирование этого файла выполняется путем запуска, visudoчто гарантирует отсутствие ошибок.

l1zard
источник
Опечатка: ты имеешь в виду .bashrcвместо .bachrc.
gniourf_gniourf
0

Я не уверен, что это работает так в Linux, если предположить, что это не так, если никто не предложил это. Но вместо использования ././, чтобы вернуться в каталоги. Можете ли вы использовать кавычки, чтобы дать ему абсолютный путь? Может быть, это не дает вам доступа ко всему драйву, чтобы даже сделать это, если подумать.

Codezilla
источник
0

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

alias run-script="cd /home/user/path/to/script/ && bash script.sh"

Таким образом, вам не нужно ничего менять, чтобы это работало.

EvR2f
источник
0

Не уверен, почему никто не предложил этот, но это очень просто! Я гуглил несколько раз и не смог найти точный ответ, который я даю, поэтому я решил поделиться. IMO, но это лучшее, но самое простое решение, для меня, в любом случае, однако другие могут чувствовать и действовать по-другому.

# Place this somewhere in your .bashrc/.bash_profile/etc and edit as you see fit

YOURCOMMAND () {
  cd /path/to/directory/containing/your/script/ && ./YOURSCRIPT
}

Сначала команда 'cd' сообщает директории местоположения скриптов. Затем '&&', чтобы вы могли связать его после выполнения следующей команды. Наконец, откройте ваш скрипт так же, как вы бы выполняли его в терминале! Сохранено в вашем файле BASH и занимает 5 секунд для установки.

Надеюсь, это помогло кому-то.

AnonymousX
источник
-1

Древний вопрос, но вечный.

Решение, которое я постоянно видел, состоит в том, чтобы иметь $HOME/binкаталог и поместить его первым $PATH(через, ~/.bashrcесли он еще не существует; в некоторых системах по умолчанию он ~/binпервый $PATH). Удаление сценариев для выполнения или символических ссылок на сценарии / исполняемые файлы в другом месте - это простой способ решения проблем с путями, которые не должны затрагивать систему или других пользователей.

Если сценарию требуются дополнительные ресурсы, которые можно найти относительно его собственного местоположения (не редкость), тогда используется envvar $BASH_SOURCE. $BASH_SOURCEвсегда содержит абсолютный путь к самому выполняющемуся скрипту, независимо от значения $PWD.

Учтите следующее:

ceverett@burrito:~$ echo $PATH
/home/ceverett/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Итак, мы видим, что $HOME/binэто первое $PATH, что бы я ни вставлял, ~/binбудет работать. У меня есть демонстрационный скрипт под названием ~/bin/findme:

#!/bin/bash

echo "Running from $BASH_SOURCE"

Это может быть использовано для получения абсолютного пути к местоположению запущенного скрипта.

ceverett@burrito:~$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~$ cd foo
ceverett@burrito:~/foo$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~/foo$ cd /
ceverett@burrito:/$ findme
Running from /home/ceverett/bin/findme
zxq9
источник
(1) Хотя это и кажется полезной информацией, вопрос не задавался вопросом о том, как писать сценарии, использующие ресурсы относительно их собственного местоположения; он спросил о запуске скриптов. (2) Я не уверен, как ваш второй абзац касается вопроса. Вы предлагаете, чтобы, если я напишу сценарий, а Десмонд захочет его запустить, он должен связать его со своим личным binкаталогом? Это кажется громоздким. (3) Кроме того, это нарушает независимость местоположения. Если /home/desmond/bin/fooесть ссылка на мой скрипт, то BASH_SOURCEбудет /home/desmond/bin/foo, и скрипт не сможет найти его ресурсы.
G-Man говорит: «Восстановите Монику»
@ G-Man (1) Пользователь не предоставил много контекста. Всякий раз, когда мне задавали этот вопрос в течение последних 30 лет, он всегда находился в контексте того, что пользователь (обычно новый сисоп или разработчик) запускает смесь своих и других приобретенных сценариев для автоматизации тривиальных задач, поэтому я ответил, что путь. Это делает предположим немного сценариев знаний со стороны пользователя спрашивать. (2) Общесистемные сценарии обычно устанавливаются /binили находятся в известном месте /opt. (3) Независимость от местоположения - это именно то, что сохраняется при написании взаимозависимой коллекции личных сценариев.
zxq9