Запуск сценаріїв з іншого каталогу


10

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

Чи є гарною практикою запуск сценаріїв (BASH, Perl тощо) з іншого каталогу? Чи зазвичай вони знайдуть усі необхідні речі для належного виконання?

Якщо так, то який найкращий спосіб запустити "далекий" сценарій? Є це

. /path/to/script

або

sh /path/to/script

і як користуватися sudoв таких випадках? Наприклад, це не працює:

sudo . /path/to/script

Будьте в курсі, що . /path/to/script джерела сценарію! Період вам взагалі не потрібен, якщо ви просто хочете його запустити.
gniourf_gniourf

Відповіді:


13

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) Symlink до /usr/bin

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

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

2) Додайте сценарій dir до свого шляху (використовуючи .bash_profile - або будь-який інший.profile, який у вас на оболонці)

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

3) Створіть псевдоніми .bash_profile в ~/.bash_profileдодатку додати щось на зразок:

alias l="ls -l"

Як ви можете сказати, синтаксис - це просто псевдонім, цифри, які ви хочете виконувати як команда, команда. Отже, набравши "l" в будь-якій точці терміналу, це призведе до того, що ls -l ви хочете судо, просто alias sl="sudo ls -l"зауважте себе l vs sl (як марний приклад).

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


Я б дуже рекомендував варіант 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що забезпечує відсутність помилок.


Опечатка: ви маєте на увазі .bashrcзамість .bachrc.
gniourf_gniourf

0

Я не впевнений, що він працює так у Linux, якщо припустити, що ніхто не запропонував це. Але замість використання ././ для повернення каталогів. Чи можете ви використовувати лапки, щоб надати йому абсолютний шлях? Можливо, це не дає вам доступу до всього диска, щоб навіть мати можливість це зробити насправді.


0

Якщо у вас є сценарії, які вам потрібно часто запускати, і вони залежать від їх розташування для пошуку ресурсів, ви можете це легко зробити, просто комбінуючи команди в псевдонімі, як це.

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

Таким чином, вам не потрібно нічого змінювати, щоб це працювало.


0

Не впевнений, чому ніхто не запропонував цього, але це дуже просто! Я декілька разів гугла, і не могла знайти точну відповідь, яку я даю, тому я подумала, що поділюсь. ІМО, це, але найкраще рішення, і найлегше для мене в будь-якому випадку, проте інші можуть відчувати і робити щось по-іншому.

# 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 секунд.

Сподіваюся, це комусь допомогло.


-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

(1) Хоча ця інформація і є корисною інформацією, питання не запитувало, як писати сценарії, що використовують ресурси щодо їх власного місцезнаходження; він запитував про запуск сценаріїв. (2) Я не впевнений, як ваш другий абзац вирішує питання. Ви припускаєте, що якщо я напишу сценарій і Десмонд хоче запустити його, він повинен зв’язати його у своєму приватному binкаталозі? Це здається громіздким. (3) Крім того, це порушує незалежність місцезнаходження. Якщо /home/desmond/bin/fooє посилання на мій сценарій, то BASH_SOURCEбуде /home/desmond/bin/foo, і сценарій не зможе знайти свої ресурси.
G-Man

@ G-Man (1) Користувач не надав особливого контексту. Щоразу, коли мені задавали це питання протягом останніх 30 років, він завжди був у контексті, коли користувач (зазвичай це новий sysop або розробник) виконує суміш власних та інших придбаних сценаріїв для автоматизації тривіальних завдань, тож я відповів на це, що шлях. Це робить припустимо трохи сценаріїв знань з боку користувача питати. (2) Загальносистемні сценарії зазвичай встановлюються в /binабо відомому місці в /opt. (3) Незалежність від місця розташування - це саме те, що зберігається під час написання взаємозалежної колекції персональних сценаріїв.
zxq9
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.