У меня ушло почти 10 лет использования Linux, чтобы задать этот вопрос. Все это было методом проб и ошибок и случайным ночным интернет-серфингом.
Но людям не нужно 10 лет для этого. Если бы я только начинал с Linux, я бы хотел знать: когда использовать псевдоним, когда писать сценарий и когда писать функцию?
Что касается псевдонимов, я использую псевдонимы для очень простых операций, которые не принимают аргументов.
alias houston='cd /home/username/.scripts/'
Это кажется очевидным. Но некоторые люди делают это:
alias command="bash bashscriptname"
(и добавьте его в .bashrc
файл)
Есть ли хорошая причина для этого? Я очень стараюсь, но я искренне не могу вспомнить ни одного обстоятельства, при котором я бы хотел это сделать. Итак, если есть крайний случай, когда это будет иметь значение, пожалуйста, ответьте ниже.
Потому что именно здесь я просто поместил бы что-нибудь в мою PATH и chmod +x
это, и это еще одна вещь, которая пришла после многих лет проб и ошибок в Linux.
Что подводит меня к следующей теме. Например, я добавил скрытую folder ( .scripts/
) в домашнем каталоге в свой PATH, просто добавив строку в my .bashrc
( PATH=$PATH:/home/username/.scripts/
), чтобы все выполняемые там файлы автоматически выполнялись автоматически.
Если бы мне было нужно.
Мне правда это не нужно, правда? Я бы использовал это только для языков, которые не являются оболочкой, таких как Python.
Если это оболочка, я могу просто написать функцию в том же самом .bashrc
:
funcname () {
somecommand -someARGS "$@"
}
Как я уже говорил, я обнаружил многое из этого методом проб и ошибок. И я по-настоящему видел всю прелесть функций, когда мой компьютер умер, и я был вынужден использовать компьютеры окружающих меня людей, когда они их не использовали.
Вместо того, чтобы переносить весь каталог скриптов с компьютера на компьютер, я просто заменил чужой .bashrc своим собственным, так как они никогда не делали ни одной модификации.
Но я что-то пропустил?
Итак, что бы вы сказали начинающему пользователю Linux о том, когда использовать псевдоним, когда писать сценарий и когда писать функцию?
Если это не очевидно, я предполагаю, что люди, которые ответят на это, будут использовать все три варианта. Если вы используете только псевдонимы или только сценарии, или используете только функции - или если вы используете только псевдонимы и сценарии или псевдонимы и функции или сценарии и функции - этот вопрос на самом деле не нацелен на вас.
источник
Ответы:
Псевдоним не должен (вообще) делать больше, чем изменять параметры команды по умолчанию. Это не более чем простая замена текста в имени команды. Он не может ничего сделать с аргументами, но передает их команде, которую он на самом деле выполняет. Поэтому, если вам просто нужно добавить аргумент в начале одной команды, псевдоним будет работать. Общие примеры
Функция должна использоваться, когда вам нужно сделать что-то более сложное, чем псевдоним, но это не будет полезно само по себе. Например, возьмите этот ответ на вопрос, который я задал, об изменении
grep
поведения по умолчанию в зависимости от того, находится ли оно в конвейере:Это прекрасный пример функции, потому что она слишком сложна для псевдонима (требующего разных значений по умолчанию в зависимости от условия), но это не то, что вам понадобится в неинтерактивном скрипте.
Если вы получаете слишком много функций или функций слишком большого размера, поместите их в отдельные файлы в скрытом каталоге и отправьте в ваш
~/.bashrc
:Скрипт должен стоять сам по себе. Он должен иметь значение как нечто, что можно использовать повторно или использовать для более чем одной цели.
источник
.
илиsource
- скрипт выполняется отдельным процессом bash и имеет свою собственную среду. По этой причине все, что изменяет среду оболочки (например, функции, переменные и т. Д.), Не сохраняется в среде оболочки, из которой вы запускаете скрипт.Другие ответы предоставляют некоторые мягкие общие рекомендации, основанные на личном вкусе, но игнорируют многие относящиеся к делу факты, которые следует учитывать при выборе между сценариями, функциями или псевдонимами.
Псевдонимы и функции ¹
Сценарии
$PATH
поиска, многие оболочки хранят в памяти хэш своего имени пути, чтобы сэкономить время при последующих поисках,$PATH
но это означает, что объем памяти, занимаемой сценарием, не используется.Скрипты могут вызываться разными способами, чем функции и псевдонимы. Они могут быть переданы в качестве аргумента интерпретатору, например
sh script
, или вызваны непосредственно как исполняемый файл, и в этом случае интерпретатор в строке shebang (например#!/bin/sh
) вызывается для его запуска. В обоих случаях сценарий запускается отдельным процессом интерпретатора со своей собственной средой, отдельной от среды вашей оболочки, на среду которой скрипт никак не может повлиять. Действительно, оболочка интерпретатора даже не должна соответствовать вызывающей оболочке. Поскольку сценарии, вызываемые таким образом, ведут себя как любой обычный исполняемый файл, они могут использоваться любой программой.Наконец, скрипт может быть прочитан и запущен текущей оболочкой с помощью
.
или в некоторых оболочкахsource
. В этом случае скрипт ведет себя как функция, которая читается по требованию, а не постоянно хранится в памяти.заявка
Учитывая вышеизложенное, мы можем придумать некоторые общие рекомендации относительно того, следует ли создавать что-то в виде скрипта или функции / псевдонима.
Нужно ли другим программам помимо вашей оболочки использовать его? Если так, то это должен быть скрипт.
Вы хотите, чтобы он был доступен только из интерактивной оболочки? Обычно требуется изменить поведение многих команд по умолчанию при интерактивном запуске, не затрагивая внешние команды / сценарии. В этом случае используйте псевдоним / функцию, установленный в rc-файле оболочки «only-mode-only» (для
bash
этого есть.bashrc
).Нужно ли менять среду оболочки? И функция / псевдоним или исходный скрипт являются возможными вариантами.
Это то, что вы часто используете? Вероятно, более эффективно хранить его в памяти, поэтому, если возможно, сделайте его функцией / псевдонимом.
И наоборот, это то, что вы используете редко? В этом случае нет смысла использовать память, когда она вам не нужна, поэтому сделайте это сценарием.
Functions Хотя у функций и псевдонимов есть некоторые важные различия, они сгруппированы вместе, потому что функции могут делать все, что могут псевдонимы. Псевдонимы не могут иметь локальных переменных и не могут обрабатывать аргументы, и они неудобны для чего-либо длиннее одной строки.
² Каждый запущенный процесс в системе Unix имеет среду, состоящую из
variable=value
пары пар, которые часто содержат глобальные параметры конфигурации, например,LANG
для локали по умолчанию иPATH
для указания исполняемого пути поиска.источник
alias g='gradle'
автодополнение Gradle при использовании своегоg
псевдонима, но не получая его из коробки при использовании сценарияgradle $*
или функции сgradle $@
Я думаю, что это на вкус каждого человека. Для меня логика выглядит так:
Там действительно нет ничего, чтобы ограничить вас от того, что делает что-то, что работает .
источник
По крайней мере, частично это вопрос личного вкуса. С другой стороны, есть некоторые четкие функциональные различия:
Что касается сценариев оболочки, которые я делал последние несколько лет, я более или менее прекратил писать псевдонимы (потому что все они имеют тенденцию превращаться в функции со временем) и выполняю сценарии только в том случае, если они должны быть доступны также и из не-bash-сред.
PS:
alias command="bash bashscriptname"
я не вижу никакой причины делать это. Даже еслиbashscriptname
не в $ PATH, простогоalias c=/path/to/script
будет достаточно.источник
alias command="bash bashscriptname"
скрипте не обязательно должен быть исполняемый файл; вalias c=/path/to/script
это должно.exec()
функции оболочки» :-)Вот некоторые дополнительные пункты об алиасах и функциях:
Например:
Как мы видим, существуют отдельные пространства имен для псевдонимов и функций; Более подробную информацию можно найти с помощью
declare -A -p BASH_ALIASES
иdeclare -f f
, которая печатает их определения (оба хранятся в памяти).Пример, показывающий ограничения псевдонимов:
Как мы видим, псевдонимы не являются вложенными, в отличие от функций. Также их использование ограничено интерактивными сессиями.
Наконец, обратите внимание, что вы можете иметь произвольные вычисления в псевдониме, объявив функцию a, немедленно вызывающую ее, например:
который уже широко используется в случае псевдонимов Git. Преимущество этого перед объявлением функции заключается в том, что ваш псевдоним не может быть просто перезаписан путем
.
создания (или использования ) сценария, который объявляет функцию с тем же именем.источник
Когда писать сценарий ...
export
переменных ed и / или функций передаются по значению в сценарий. Изменения в этих переменных не распространяются обратно на родительский скрипт.Когда написать функцию ...
Когда писать псевдоним ...
~/.profile
или~/.bashrc
.В сценариях, таких как библиотечные сценарии, иногда необходим псевдоним для функции, например, когда функция переименована, но требуется обратная совместимость. Это может быть достигнуто путем создания простой функции со старым именем, которая передает все свои аргументы новой функции ...
источник
Еще одна вещь, в которую я не верю, была затронута: функция выполняется в контексте вызывающего процесса, в то время как сценарий разветвляется на новую оболочку.
Это может быть важно для производительности - функция быстрее, потому что это не так
fork()
иexec()
. В обычных обстоятельствах это различие тривиально, но если вы отлаживаете систему, в которой недостаточно памяти и которая перебирает страницы, это может иметь большое значение.Кроме того, если вы хотите изменить текущую среду оболочки, вы должны использовать функцию. Например, функция может изменить поиск команд
$PATH
для текущей оболочки, а сценарий - нет, поскольку работает с копией fork / exec$PATH
.источник
export -f
использовать функцию, хотя точная внутренняя работа этого не совсем ясна. Я считаю, что это не переносимо для традиционной оболочки Bourne.Скрипт и псевдоним, а также скрипт и функция не являются взаимоисключающими. Вы можете хранить псевдонимы и функции в скриптах.
Скрипты - это просто код, который сделан постоянным . Полезные функции и псевдонимы, которые вы хотели бы использовать в будущем, хранятся в скриптах. Однако сценарий часто представляет собой набор из более чем одной функции.
Поскольку псевдонимы не параметризованы , они очень ограничены; обычно для определения некоторых параметров по умолчанию.
Функция представляет собой отдельный блок кода , четко определенная концепция нескольких строк коды , которые не могут разделены на более мелкие, полезные части; тот, который может быть повторно использован непосредственно или другими другими функциями.
источник
Если это должно быть очень быстро, сделайте его псевдонимом или функцией.
Если он должен использоваться вне вашей предпочитаемой оболочки, сделайте его сценарием. 1
Если он принимает аргументы, сделайте это функцией или скриптом.
Если он должен содержать специальные символы, сделайте его псевдонимом или скриптом. 2
Если ему нужно работать с sudo, сделайте его псевдонимом или скриптом. 3
Если вы хотите легко изменить его, не выходя из системы и не входя в нее, скрипт станет проще. 4
Сноски
1 Или сделайте его псевдонимом, вставьте
~/.env
и установитеexport ENV="$HOME/.env"
, но сложно заставить его работать переносимо.2 Имена функций должны быть идентификаторами, поэтому они должны начинаться с буквы и могут содержать только буквы, цифры и символы подчеркивания. Например, у меня есть псевдоним
alias +='pushd +1'
. Это не может быть функцией.3 И добавьте псевдоним
alias sudo='sudo '
. То же самое относится и к любой другой команде, такой какstrace
,gdb
и т. Д., Которая принимает команду в качестве первого аргумента.4 Смотрите также: fpath. Конечно, вы также можете сделать
source ~/.bashrc
или подобное, но это часто имеет другие побочные эффекты.источник
+
в bash. Интересно, что после тестирования я обнаружил, что в bash вы можете создать+
псевдоним, но не функцию, как вы говорите, но zsh - наоборот -+
может быть функцией, но не псевдонимом.zsh
вас есть писатьalias -- +='some command here'
.+
переносимы. См.sudo
использования. Что касается сноски 4, я храню свои псевдонимы~/.bash_aliases
и определения функций,~/.bash_functions
чтобы я мог легкоsource
их перечитать (без опасности побочных эффектов).Просто чтобы добавить несколько заметок:
Кроме этого, вы можете использовать простейшую форму, то есть сначала рассмотреть псевдоним, затем функцию, затем скрипт.
источник
sudo
. Но сначала тебе нужноalias sudo='sudo '
.Мое эмпирическое правило:
источник
В многопользовательской (или многопользовательской) среде я использую сценарии для всего, даже если это просто короткая обертка «exec what ....».
Конечно, это технически медленнее / менее эффективно, чем псевдоним или функция, но это почти никогда не имеет значения - и при условии, что он находится в пути, скрипт всегда работает.
Ваша функция может быть вызвана из cron, из чего-то с ограниченной или измененной средой, такой как sudo или env, или пользователь может просто использовать другую оболочку для вас - все или которая может нарушить псевдоним или функцию.
Если у вас есть что-то чувствительное к производительности, рассматривайте это как особый случай или, что еще лучше, учтите, что это триггер для перезаписи на более функциональном языке сценариев.
Если мы говорим о функциях, которые будут использоваться только в других сценариях, то вы можете также рассмотреть определение стандартной оболочки и написание сценария библиотеки функций, который может быть просто. Источник я для всех других сценариев.
T
источник
Пример ситуации, когда вы, скорее всего, хотели бы использовать псевдоним.
Я знаю, что это старый пост, но я хотел бы указать на ситуацию, когда мне почти пришлось использовать комбинацию псевдонима со сценарием, и я решил не использовать функцию.
У меня есть сценарий с
~/.bin/
именем ,setup
который выполняет следующие действия : 1Дело в том, что если бы я просто запустил, у
setup <project-name>
меня не было бы этих переменных, и я бы вообще не попал в каталог. Лучшим решением, которое я нашел, было добавление этого сценарияPATH
и добавлениеalias setup=". ~/.bin/setup"
к нему~/.bashrc
или что-то еще.Примечания:
источник
Когда писать сценарий
Когда вы можете захотеть запустить команду из инструмента, отличного от оболочки.
Это включает в себя vim (для меня): написав фильтры и другие программы в виде скриптов, я могу сделать что-то вроде
:%!my-filter
фильтрации файла через программу из моего редактора.Если бы
my-filter
это была функция или псевдоним, это было бы невозможно.источник