# Deep Dive In Terminal

1) [difference between a builtin and a keyword](https://askubuntu.com/a/590335)

## В командной строке Linux существует 6 типов команд:

❗В Bash приоритеты поиска команд при выполнении команды указаны в следующем порядке:

* **Ключевые слова (keyword)** – если это зарезервированное слово для [bash скриптинга](./1.3.3%20CLI/1.3.3.1%20Shells.md) (например, [time (что удивительно)](https://askubuntu.com/a/1054460), if, then и т. д.);
    > Пример: 
    > type time // time is a shell (reserved) keyword

* **Встроенные/внутренняя команда (shell builtins)** – команды реализована как функци внутри самой командной оболочки bash/zsh;
    > Пример: 
    > type -a type 
    > // type is a shell builtin - это встроенная команда
    > // type is /usr/bin/type - это внешняя команда (ниже описание)

* **[Функции](/2%20ComputerScience/2.2%20Languages/2.2.2%20Paradigm/2.2.2.1%20Declarative/2.2.2.1.1%20FunctionalProgramming(FP).md) командной оболочки ([shell functions](https://bash.cyberciti.biz/guide/Writing_your_first_shell_function))** — сценарии на языке командной оболочки, встроенные в окружение;
    > Пример: 
    > my_function() { echo "This is a shell function"; }
    > 
    > type my_function // my_function is a shell function

* **Псевдоним или alias** — это команда, которую мы можем определить сами, сконструировав ее из других команд;
    > Пример: 
    > type l // l is an alias for ls -lah

* **Внешняя команда (File, внешний исполняемый файл/выполняемая программа)** - располагаются в каталогах /bin, /sbin, /usr/bin и т.д. Также: скомпилированные двоичные программы: на C и C++, shell, Perl, Python, Ruby и др. 
    > Пример: 
    > ищется по переменной окружения $PATH
    > echo -e ${PATH//:/\\n}

    > ❗Команда `command` предназначена для вызова файлов отсюда, не из shell builtins (внутренней). `command time` == вызову /usr/bin/time

* **nothing (пустой вывод)** – если команда не найдена;
    > Пример: 
    > type nonexistent_command
    > nonexistent_command not found

Команда `type` показывает тип команды:
* `type -t` - более лаконичный ответ в одно слово;
* `type -a` - чтобы распечатать все совпадения;

## keyword vs shell builtins

Source: [difference between a builtin and a keyword](https://askubuntu.com/a/590335)

Встроенная команда похожа на команду, за исключением того, что она встроена в оболочку, тогда как ключевое слово — это то, что позволяет реализовать сложное поведение! Мы можем сказать, что это часть грамматики оболочки.

### Иерархия на примере:
Предположим, вы вызываете команду echo:
* Bash проверяет, является ли echo ключевым словом (нет, это не ключевое слово);
* Проверяет, встроенная ли это команда (да, echo — встроенная команда);
* Если бы вы определили функцию echo, она бы выполнилась вместо встроенной команды;
* Если бы вы создали псевдоним для echo, он бы использовался только при отсутствии функции с таким именем;
* Если бы не существовало ничего выше, Bash искал бы внешнюю команду echo в $PATH;

### Зачем разделать внутреннюю (shell builtins) и внешнюю команду?

Команды делаются встроенными:

* либо из соображений производительности - исполняются быстрее, чем внешние, которые, как правило, запускаются в дочернем процессе;

* либо из-за необходимости прямого доступа к внутренним структурам командного интерпретатора;

## Команды анализ бинарников

| **Наименование** | **Ключевые различия** | **Функция** | **Особенности на macOS** | **Пример использования** |
|-------------|-------------|-------------|--------------------------|---------------------------|
| **`command`** | Анализ и вызов команды | Выполняет команду, игнорируя алиасы и функции. | Может отображать алиасы, если они настроены | `command time -h echo "Hello"` вызовет внешнюю команду (не shell builtins) == `/usr/bin/time -h echo "Hello"`. Но! просто команда time вызовет  shell builtins (встроенную команду): `time -h echo "Hello" // -h not found` |
| **`type`**  | Анализ команд | Определяет, как shell интерпретирует команду (alias, встроенная, путь). | Показывает детали встроенных команд, алиасов и внешних бинарников. | `type ls` → `ls is /bin/ls` |
| **`which`** |  Анализ команд | Показывает путь к исполняемой команды только из переменной $PATH | Работает только с внешними программами. | `which python` → `/usr/bin/python` |
| **`whereis`** | Команды поиска файлов | Игнорирует $PATH, что делает whereis **бесполезной** когда бинарники в $PATH (н/р для Python, [Node.js](/4%20Linkage/4.2%20DevTools/4.2.1%20Building/4.2.1.0%20PackageManager/4.2.1.0.2%20NodePM.md), [Homebrew](/4%20Linkage/4.2%20DevTools/4.2.1%20Building/4.2.1.0%20PackageManager/4.2.1.0.1%20Homebrew.md)), тк она не будет искать в них. ❗ Но все равно найдет исполняемый файл, даже если ваш $PATH пуст. | Быстра, но ограничено базой user.cs_path. На macOS устарела. | `whereis python` → `/usr/bin/python` |

![](/pictures/Common/DeepDiveInTerminal.png?raw=true)

## Команда для поиска файлов

| **Наименование** | **Ключевые различия** | **Функция** | **Особенности на macOS** | **Пример использования** |
|-------------------------------|-----------------------|-------------|--------------------------|---------------------------|
| **`mdfind`** | Использует индекс Spotlight, быстрый поиск. | Ищет файлы по имени, содержимому и метаданным. | `mdfind "project"` → Ищет файлы с "project". |
| **`find`** | Обходит файловую систему напрямую. | Универсальный поиск по имени, дате, размеру и другим параметрам. | `find / -name report.txt` → Ищет файл по всему диску. |
| **`locate`** | Ищет не на диске, а в индексе, который обновляется ежедневно из cron. Поэтому свежесозданных файлов он не найдёт | Быстро ищет файлы по имени. | `locate report.txt` → Ищет файл по имени. |

### Что такое переменная $PATH?

В Linux и Unix-подобных системах переменная PATH содержит перечень путей, по которым хранятся исполняемые программы, например ping, date, vi, docker и так далее. Чтобы просмотреть текущую переменную path, воспользуйтесь командой `echo /printf`:

```bash
echo $PATH
# OR
# More human readable format 
echo "${PATH//:/$'\n'}"
```

### Файловая система Linux: [ссылка](/2%20ComputerScience/2.0%20Linux/2.0.3%20FileSystemLinux.md)

В линукс обычно исполняемые файлы лежат в `/bin`, `/sbin`, `/usr/bin`, `/usr/sbin`.
Иногда в `/usr/local/bin`, `/usr/local/sbin`.
Еще некоторый софт (пример: [homebrew](/4%20Linkage/4.2%20DevTools/4.2.1%20Building/4.2.1.0%20PackageManager/4.2.1.0.1%20Homebrew.md)) ставит себя в `/opt` и там в собственном подкаталоге создает похожую иерархию каталогов.







// TODO: доописать про приоритет
Приоритет выполнения команд в Bash:
Алиас – если определен.
Функция shell – если определена.
Встроенная команда shell (builtin).
Исполняемый файл – ищется в $PATH.




---

[1.3.0 Terminal Theme](./1.3.0%20Terminal.md) | [Back To iTWiki Contents](https://github.com/eldaroid/iTWiki) |  [1.3.2 Text Editors Theme](./1.3.2%20TextEditors/)