Яка різниця міжкомандами
setтаenvкомандами?Коли / слід використовувати один на відміну від іншого?
Як вони взагалі викликаються? (Типове використання; сценарій випадку).
Яка різниця міжкомандамиsetтаenvкомандами?
Коли / слід використовувати один на відміну від іншого?
Як вони взагалі викликаються? (Типове використання; сценарій випадку).
Відповіді:
setце команда вбудованої оболонки .
(Оскільки це питання позначено оболонками Unix, я опускаю команду MS Windows.)
setВбудована команда визначена в стандарті POSIX з рядом особливостей.
Основне призначення setвбудованого - це
встановити або скасувати параметри та позиційні параметри.
Позиційні параметри передаються оболонці (зазвичай це сценарій - але може бути інтерактивним) як аргументи викликаючої програми - зазвичай (але не обов'язково) інший оболонку. Перший параметр доступний як $1, другий як $2і т.д.
setКоманда може управляти цими параметрами. Кожен поданий йому аргумент встановлюється як позиційний параметр, наприклад
$ set one two
$ echo "$1"
one
$ echo "$2"
two
set -- знімає всі позиційні параметри:
$ set --
$ echo $1 # no output
Однак специфікація POSIX також описує інші види використання для set:
Запуск setсам по собі друкує імена та значення всіх змінних оболонок. Це включає
Приклад:
$ set
HOME='/home/ant'
IFS='
'
LANG='en_US.UTF-8'
LANGUAGE='en_US:en'
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PS1='# '
PS2='> '
PS4='+ '
PWD='/home/ant'
У наведеному вище списку, HOME, LANGі PATHє змінними середовищами в той час як IFSі PS1для PS4всіх змінних оболонок , які були встановлені в поточній оболонці.
Примітка. В оболонці Bash setвбудований також друкує визначення функцій оболонки. Для отримання додаткової інформації див. Посібник Bash для набору.
setтакож використовується для управління атрибутами оболонки, зазвичай (але не обов'язково) інтерактивну оболонку. Це робиться, запустивши його з певними заздалегідь визначеними параметрами (щоб відрізнити їх від аргументів, які використовуються для встановлення позиційних параметрів, як описано вище).
Коли параметри вказані, вони повинні встановлювати або скасовувати атрибути оболонки
Ці параметри детально описані в специфікації POSIX . Одним із прикладів є
set -f
-fПараметр відключає розширення імені шляху (підстановку) від здійснюються з допомогою поточної оболонки. Ця поведінка також може бути налаштована за допомогою еквівалентної команди:
set -o noglob
Оболонки, такі як Bash, розширюються в цьому списку, включаючи такі параметри, як -B(або -o braceexpand); це вмикає розширення дужок (функції лише для Bash) у поточній оболонці.
На відміну від цього set, envкоманда є звичайною зовнішньою командою, тобто не є частиною оболонки. За умовами (для портативності), у кожному середовищі Unix envпрограма є виконуваним файлом, встановленим в /usr/binкаталог.
envІнструмент також визначається POSIX .
Основна мета envкоманди - запуск команди з іншим / модифікованим середовищем.
env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
Наступний приклад запускає git statusкоманду з набором двох змінних середовища:
env GIT_DIR=~/notes/.git/ GIT_WORK_TREE=~/notes/ git status
-iВаріант з envможе бути використаний для виконання команди з порожньою середовищем, тобто ніякі змінні оточення не успадковуються від батьківського процесу.
Зауважте, що якщо тільки змінити одну або дві змінні середовища та використовувати оболонку Bash, немає необхідності, envоскільки сам Bash може тимчасово змінювати середовище для однієї команди. У Bash, наведений вище приклад можна було просто запустити так:
GIT_DIR=~/notes/.git/ GIT_WORK_TREE=~/notes/ git status
Якщо команда не надається, друкується поточне середовище.
$ env
MAIL=/var/mail/root
LANGUAGE=en_US:en
USER=ant
HOME=/home/ant
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=en_US.UTF-8
Зауважте, що це друкує лише змінні середовища, а не змінні оболонки, такі як PS1або IFS.
Ще одне використання env- пошук команди PATH для команди.
Він також може бути використаний для запуску зовнішньої команди, затіненої командною оболонкою. Оскільки він нічого не знає про вбудовані оболонки, ключові слова, функції чи псевдоніми (все, що визначено оболонкою та оболонкою), він шукає виконувані файли в каталогах, визначених PATHзмінною оточення.
З використання системної команди замість вбудованого Bash, не вказуючи повний шлях
envзапускає виконуваний файл, названий його першим аргументом, у (можливо) модифікованому середовищі; як такий, він не знає про та не працює з вбудованими командами оболонки.
Наприклад, ця команда запустить вбудовану оболонку версії echo:
$ echo --version
--version
З іншого боку, запуск echoчерез envвиконує програму, встановлену в /usr/bin/echo:
$ env echo --version
echo (GNU coreutils) 8.15
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Вищевказана поведінка часто використовується для використання в shebang (перший рядок) виконуваного сценарію, щоб гарантувати, що ядро використовує правильну програму для інтерпретації сценарію, - не потрібно вказувати, в якому каталозі встановлена програма інтерпретатора.
Наприклад, Python встановлюється в різних місцях в різних системах (немає стандартного місця розташування). Наступний шебанг призведе до запуску сценарію python3програмою, доки він встановлений в одному з каталогів, зазначених у PATHзмінній оточення.
#!/usr/bin/env python3
Це використання можна перевірити в інтерактивній оболонці, ввівши в командному рядку наступне:
$ /usr/bin/env python3 --version
Python 3.2.5
З цієї чудової відповіді на тему "Як / usr / bin / env знає, яку програму використовувати?"
Ядро не хоче знати про такі змінні середовища, як
PATH. Отже, ім'я в рядку shebang має бути абсолютним шляхом до виконуваного файлу.Основна мета
envкоманди - запустити команду з іншим середовищем, але оскільки вона шукає ім'я команди в$PATH, її можна використовувати для надання шляху команди до ядра .Хоча це офіційно не гарантовано, історичні системи Unix при умови ,
envв/usr/bin, і сучасні системи зберегли це місце саме через широкого використання#!/usr/bin/env.
В основному, використання envє більш портативним, оскільки означає, що сценарію не потрібно знати, де встановлено бажаний бінарний файл для команди запуску. Дивіться також Чому краще використовувати "#! / Usr / bin / env NAME" замість "#! / Path / to / NAME" як мій шебанг?