Что такое shell в linux
Перейти к содержимому

Что такое shell в linux

  • автор:

Introducing the Shell

Humans and computers commonly interact in many different ways, such as through a keyboard and mouse, touch screen interfaces, or using speech recognition systems. The most widely used way to interact with personal computers is called a graphical user interface (GUI). With a GUI, we give instructions by clicking a mouse and using menu-driven interactions.

While the visual aid of a GUI makes it intuitive to learn, this way of delivering instructions to a computer scales very poorly. Imagine the following task: for a literature search, you have to copy the third line of one thousand text files in one thousand different directories and paste it into a single file. Using a GUI, you would not only be clicking at your desk for several hours, but you could potentially also commit an error in the process of completing this repetitive task. This is where we take advantage of the Unix shell. The Unix shell is both a command-line interface (CLI) and a scripting language, allowing such repetitive tasks to be done automatically and fast. With the proper commands, the shell can repeat tasks with or without some modification as many times as we want. Using the shell, the task in the literature example can be accomplished in seconds.

The Shell

The shell is a program where users can type commands. With the shell, it’s possible to invoke complicated programs like climate modeling software or simple commands that create an empty directory with only one line of code. The most popular Unix shell is Bash (the Bourne Again SHell — so-called because it’s derived from a shell written by Stephen Bourne). Bash is the default shell on most modern implementations of Unix and in most packages that provide Unix-like tools for Windows. Note that ‘Git Bash’ is a piece of software that enables Windows users to use a Bash like interface when interacting with Git.

Using the shell will take some effort and some time to learn. While a GUI presents you with choices to select, CLI choices are not automatically presented to you, so you must learn a few commands like new vocabulary in a language you’re studying. However, unlike a spoken language, a small number of “words” (i.e. commands) gets you a long way, and we’ll cover those essential few today.

The grammar of a shell allows you to combine existing tools into powerful pipelines and handle large volumes of data automatically. Sequences of commands can be written into a script, improving the reproducibility of workflows.

In addition, the command line is often the easiest way to interact with remote machines and supercomputers. Familiarity with the shell is near essential to run a variety of specialized tools and resources including high-performance computing systems. As clusters and cloud computing systems become more popular for scientific data crunching, being able to interact with the shell is becoming a necessary skill. We can build on the command-line skills covered here to tackle a wide range of scientific questions and computational challenges.

Let’s get started.

When the shell is first opened, you are presented with a prompt, indicating that the shell is waiting for input.

The shell typically uses $ as the prompt, but may use a different symbol. In the examples for this lesson, we’ll show the prompt as $ . Most importantly, do not type the prompt when typing commands. Only type the command that follows the prompt. This rule applies both in these lessons and in lessons from other sources. Also note that after you type a command, you have to press the Enter key to execute it.

The prompt is followed by a text cursor, a character that indicates the position where your typing will appear. The cursor is usually a flashing or solid block, but it can also be an underscore or a pipe. You may have seen it in a text editor program, for example.

Note that your prompt might look a little different. In particular, most popular shell environments by default put your user name and the host name before the $ . Such a prompt might look like, e.g.:

The prompt might even include more than this. Do not worry if your prompt is not just a short $ . This lesson does not depend on this additional information and it should also not get in your way. The only important item to focus on is the $ character itself and we will see later why.

So let’s try our first command, ls , which is short for listing. This command will list the contents of the current directory:

Что такое bash в Linux? Гайд по созданию bash-скриптов

bash (сокр. от «Bourne-Again shell») — это командная оболочка (или «интерпретатор командной строки»), используемая по умолчанию в операционных системах на базе Unix и Linux, созданная в 1989 году Брайаном Фоксом с целью усовершенствования командной оболочки sh.

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

Что такое терминал?

Терминал — это программа, которая используется для взаимодействия с шеллом. Это просто интерфейс к нему и другим программам командной строки, которые работают внутри нее. Вот как выглядит типичный терминал (Konsole) в Debian 11 (окружение рабочего стола — KDE Plasma):

Типичный терминал в Linux

Всякий раз, когда мы открываем окно терминала, мы видим приглашение шелла — имя_пользователя@имя_машины:

$ . Символ $ означает, что мы работаем под учетной записью обычного пользователя, а символ

(тильда) означает, что в данный момент мы находимся в домашнем каталоге /home/<имя_пользователя>.

Команды в bash

Команда в bash — это наименьшая единица кода, которую bash может выполнить. С помощью команд мы сообщаем шеллу, что нам нужно, чтобы он сделал. bash обычно принимает от пользователя одну команду и возвращается к нему после того, как команда будет выполнена. Чтобы немного освоиться в bash, давайте попробуем выполнить несколько простых команд.

Команда echo — возвращает всё, что вы вводите в командной строке:

Пример использования команды echo

Команда date — отображает текущее время и дату:

Пример использования команды date

Команда pwd (сокр. от «print working directory») — указывает на текущий рабочий каталог, в котором команды шелла будут искать файлы.

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

Пример использования команды pwd

Команда ls (сокр. от «lis) — отображает содержимое каталога. Обычно, команда ls начинает с просмотра нашего домашнего каталога. Это означает, что если мы просто напечатаем ls , то данная команда выведет содержимое текущего каталога, которым в нашем примере является домашний каталог /home/diego:

Пример использования команды ls

Команда cd (сокр. от «change directory») — изменяет текущую директорию на заданную пользователем. Рассмотрим некоторые примеры использования данной команды:

cd <директория> — меняет текущую директорию на заданную. Давайте попробуем с помощью команды ls перейти к корневому каталогу / и ознакомимся с его содержимым. Обратите внимание, что мы также можем использовать точку с запятой ; для записи двух команд в одной строке.

Пример объединения двух команд в одной строке

cd .. — вернуться в родительский каталог.

cd — вернуться в домашний каталог.

Команда mkdir (сокр. от «make directory») создает новый каталог.

Команда mv (сокр. от «mov) — перемещает один или несколько файлов/каталогов из одного места в другое (заданное пользователем). Для этого нужно указать, что мы хотим переместить (т.е. источник), и куда мы хотим переместить (т.е. пункт назначения).

В качестве примера я создам новый каталог Ravesli в своей домашней директории и перемещу в него все .txt-файлы (ну как «все», у меня там только один файл — Адреса.txt) из /home/diego/Документы/ с помощью двух вышеприведенных команд:

Перемещение файлов с помощью команды mv

Команда touch — создает новые пустые файлы (а также изменяет временные метки в существующих файлах и каталогах). Вот как мы можем создать пустой файл под названием foo.txt в папке Ravesli из домашнего каталога:

Создание файла с помощью команды touch

Команда rm (сокр. от «remove») — удаляет файлы/каталоги. По умолчанию, команда rm НЕ удаляет каталоги, но если используется как rm -r * внутри заданного каталога, то каждый подкаталог и файл внутри заданного каталога — удаляются.

Давайте удалим ранее созданный файл foo.txt:

Удаление файла с помощью команды rm

Команда rmdir (сокр. от «remove directory») — удаляет каталоги.

Давайте удалим созданный ранее каталог /home/diego/Ravesli:

Удаление каталогов с помощью команды rmdir

Команда cat (сокр. от «concatenate») — считывает файл и выводит его содержимое. Она может работать с несколькими файлами, объединяя их вывод в единый поток (отсюда и происходит её название). У меня в домашнем каталоге есть папка untitled с файлами С++/Qt-проекта, и ниже я использую команду cat для просмотра содержимого файла main.cpp из untitled:

Пример использования команды cat

Чтобы просмотреть несколько файлов, укажите друг за другом (через пробел) имена требуемых файлов после команды cat , например:

Просмотр нескольких файлов с помощью команды cat

Команда man (сокр. от «manual») — отображает справочные страницы, которые являются руководством пользователя, встроенным по умолчанию во многие дистрибутивы Linux и большинство систем Unix. Например, команда man bash отобразит руководство пользователя, а команда man ls отобразит справку по команде ls .

Отображение справочной информации с помощью команды man

Редактор nano

nano — это маленький, простой, консольный текстовый редактор *nix-подобных операционных систем, впервые увидевший свет в далеком 1999 году. Для запуска редактора достаточно ввести в терминале всего одну команду — nano . Если же нужно отредактировать какой-то конкретный файл, то применяется команда nanо /<путь_к_файлу/<имя_файла> . Отличительной чертой данного редактора является то, что он управляется сочетаниями клавиш. Например, для сохранения текущего документа применяется сочетание Ctrl+O, для вызова меню поиска — Ctrl+W, для выхода из редактора — Ctrl+X, а для получения всего списка доступных сочетаний клавиш — Ctrl+G.

Гайд по созданию bash-скриптов

Наш шелл, это не только промежуточное звено между пользователем и системой, но еще и мощный язык программирования. Программы, написанные на языке шелла, называются shell-скриптами (или shell-сценариями) и имеют соответствующее расширение файлов — .sh. Сам язык содержит полный набор утилит и команд, доступных в *nix-системах, а также циклы, условные операторы, объявление переменных и пр. Такие скрипты будут очень полезными там, где не требуется использование полноценных языков программирования, например, в задачах администрирования операционной системы.

Создание bash-скрипта

Чтобы создать новый файл bash-скрипта, откройте в любом редакторе текстовый файл и сохраните его с расширением .sh. Все дальнейшие эксперименты я будут проводить в Debian Linux, с применением текстового редактора nano.

Давайте создадим новый файл ravesli.sh:

$ touch ravesli.sh
diego@debian:

$ ls -l
-rw-r—r— 1 diego diego 0 мар 9 14:59 ravesli.sh
diego@debian:

Чтобы выполнить файл bash-скрипта, нужно изменить права доступа к файлу и сделать его исполняемым. Разрешение, как вы наверняка помните из предыдущих уроков, изменяется командой chmod +x <имя_файла> :

$ chmod +x ravesli.sh
diego@debian:

$ ls -l
итого 40
drwxr-xr-x 2 diego diego 4096 фев 27 00:23 build-untitled-Desktop-Debug
-rw x r- x r- x 1 diego diego 0 мар 9 14:59 ravesli.sh

Выполнение bash-скрипта

Файл bash-скрипта может быть запущен двумя способами:

Способ №1: bash <имя_файла> . Чтобы выполнить скрипт, просто напишите в терминале команду bash , а затем (через пробел) имя файла и нажмите Enter.

Способ №2: ./<имя_файла> . Чтобы выполнить скрипт введите команду ./<имя_файла> и нажмите Enter.

Что такое Shell

Если вы пользуетесь Linux, то рано или поздно, поиски решения какой-либо задачи приводили вас к терминалу. Это очень эффективное средство взаимодействия с операционной системой. Вы можете быстро выполнять нужные команды, получать результат и объединять несколько команд в цепочку. Один из самых основных компонентов терминала — это командная оболочка или Shell.

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

Что такое Shell

Shell или командная оболочка — это программа, которая организовывает среду для выполнения других программ и команд Командная оболочка имеет свои встроенные команды, арифметические операторы и другие синтаксические выражения, но основная её задача упрощать запуск других программ. Именно командная оболочка занимается поиском программ в текущем каталоге и в путях, указанных в переменной среды PATH, управляет сменой текущего каталога и переменными окружения. Таким образом, основная задача оболочки — интерпретировать команды пользователя и выполнять их не зависимо от того внешние ли это программы или внутренние команды.

Чтобы понять с чем вы имеете дело, командой оболочки или внешней программой можно воспользоваться командой whereis. Например команда cd, это не программа, а встроенная команда оболочки, как и bg и fg:

А вот команда ls — уже внешняя программа, исполняемый файл которой расположен в файловой системе.

Командная оболочка — это традиционный способ ввода данных в Unix подобных операционных системах. Командные оболочки появились почти сразу же после появления Unix и привычных нам интерфейсов взаимодействия с компьютером. Первой командной оболочкой была Thompson Shell, разработанная Кеном Томсоном в Bell Labs в 1971 году. Уже тогда поддерживалось перенаправление ввода-вывода команд с помощью туннелей, а также поддерживались простые условные операторы.

Циклы while в командных оболочках появились чуть позже, в оболочке PWB Shell, разработанной Джоном Машеу на основе Thompson Shell. Но современный вид командная оболочка приобрела только с выходом оболочки Борна (Bourne Shell) в 1979 году. В ней было уже автодополнение имен файлов и команд, стандартные переменные окружения и привычные управляющие структуры. Исполняемый файл этой оболочки имел такой путь в системе — /bin/sh. В современных системах это обычно ссылка на используемую оболочку.

Именно вдохновляясь идеями этой оболочки потом была разработана оболочка Bash (Bourne Again Shell) используемая сейчас по умолчанию в большинстве дистрибутивов Linux. Она уже была разработана Браеном Фоксом в рамках проекта GNU в 1989 году. С тех пор прошло много времени и эта оболочка сильно устарела. Поэтому были разработаны и другие более современные командные оболочки, такие как ZSH и Fish.

Оболочка Zsh появилась незадолго после Bash в 1990 году, но она уже имеет намного больше функций, например, есть автодополнение для cd, когда выводится список папок из которого можно выбрать нужную:

Поддерживается автодополнение для параметров команд, например, для git можно вывести доступные команды вместе со справкой:

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

Ещё более современная оболочка fish (Friendly Interactive Shell), появившаяся в 2005 году. Она поддерживает все стандартные возможности командной оболочки, но кроме того имеет удобную подсветку синтаксиса команд во время введения, удобный поиск команд, как Ctrl+R только по умолчанию, но самое удобное здесь это скрипты. Они намного проще для начинающих пользователей.

Если вы не меняли командную оболочку, то очень высока вероятность, что у вас используется Bash. Самый простой способ узнать какая оболочка у вас используется на данный момент, посмотреть содержимое переменной окружения SHELL:

Ещё один способ узнать текущую оболочку — воспользоваться командной ps. Если ей передать опцию -p и идентификатор процесса, то она покажет информацию о нём. Вывести идентификатор процесса текущей оболочки можно с помощью символов $$. Поэтому выполните:

В данном случае видно, что используется ZSH. Для того чтобы посмотреть все оболочки, установленные в вашей системе, просто выведите содержимое файла /etc/shells:

Все эти оболочки можно использовать выполнения команд от пользователей. Оболочка настраивается в файле /etc/passwd, для каждого пользователя отдельно. Поэтому посмотреть какая оболочка настроена для того или иного пользователя можно в этом файле. Например, для текущего пользователя команда будет выглядеть так:

grep «^$USER» /etc/passwd | awk -F: ‘< print $7>‘

Выводы

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

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Linux shell under the hood !

thomas montoya

A Shell is a command-line interpreter. It works in an interactive and non-interactive way (don’t worry more about that later).

A Shell provides you with an interface to the Unix system. It gathers input from you and executes programs based on that input. When a program finishes executing, it displays that program’s output.

Shell is an environment in which we can run our commands, programs, and shell scripts. There are different flavors of a shell, just as there are different flavors of operating systems. Each flavor of the shell has its own set of recognized commands and functions.

Shell prompt

The prompt, ($), which is called the command prompt, is generate by the shell. While the prompt is displayed, you can type a command.

Shell reads your input after you press Enter. It determines the command you want to be executed by looking at the first word of your input. A word is an unbroken set of characters. Spaces and tabs separate words.

But how ?

  • For this blog, we are going to use our own UNIX shell running on terminator in ubuntu.
  • You can find our shell with detailed information about how to use it here: https://github.com/thomasmontoya123/simple_shell.

The algorithm behind:

Interactive mode at the left, non-interactive mode at the right.

1. Check if the shell should work in interactive or non-interactive mode:

For this, we use the isatty() function. isatty() tests whether fd (file descriptor) is an open file descriptor referring to a terminal. isatty() returns 1 if fd is an open file descriptor referring to a terminal; otherwise, 0 is returned, and errno is set to indicate the error.

2. If the shell should work in an interactive mode:

Show the prompt ($ ) and wait for the user input.

3. After the user input:

After the user writes something (ls -l ) in this case and hits enter, we need to store that input somewhere, for that purpose we use the _getline() function which is our implementation of the getline() function.

getline() reads an entire line from the stream, storing the address of the buffer containing the text into *lineptr. The buffer is null-terminated and includes the newline character if one was found.

If *lineptr is NULL, then getline() will allocate a buffer to store the line, which should be freed by the user program. (In this case, the value in *n is ignored)

4. more than one-word input:

As you may know, usually the shell commands and builtins have flags, those flags are the options for that command or builtin. (-l) in this case, which means long format. The user can also write the path, where they want to perform that action. Lets see an example: list (ls) in long format (-l) in some folder (/home/thomas).

5. Split the input:

To check for those options we need to split all the input in single words, so we implemented our own strtok() function.

strtok() divides an entire string into substrings depending on the delimiter (more of that in the step by step process).

The strtok() function parses a string into a sequence of tokens. On the first call to strtok() the string to be parsed should be specified in str. In each subsequent call that should parse the same string, str should be NULL.

The delim argument (space in this case)specifies a set of bytes that delimit the tokens in the parsed string. The caller may specify different strings in delim in successive calls that parse the same string. So every time that strtok() finds a delimiter (space), the string is divided.

with _getline() we just get one string (ls -l). After strtok() we get:

  • String 1 = ls.
  • string 2 = -l.

6. Analyze the first string.

We need to check if that first substring is a command or a builtin, in this case, our first substring or token is (ls) which is a command.

A builtin is a command or a function, called from a shell, that is executed directly in the shell itself, instead of an external executable program which the shell would load and execute(more of that in about the process section of this article):

env builtin example:

We compare that first string against our builtins functions, our builtins are:

  • cd — Change the directory.
  • help — Print the shell help.
  • exit — Exit from the shell.
  • env- Print the environment variables.

As you can see ls isn’t a builtin, now we have to find out if it is a command. We don’t know where that command is (it resides on /bin/ls, ok we know but the computer doesn’t) so we need to find it, for that we built the path management. The path management searches in the computer for the command.

Without the path management:

And we don’t want to write where the command resides every single time because is a lot of effort!

With the path management:

7. About the procces.

now we are ready to run the command….. But we can’t run it in the same shell process so we created a child process using the fork() function.

fork() creates a new process by duplicating the calling process(the shell in this case). The new process is referred to as the child process (where ls is going to be executed). The calling process is referred to as the parent process.

The child process and the parent process run in separate memory spaces. At the time of fork() both memory spaces have the same content. Memory writes, file mappings, and unmapping performed by one of the processes do not affect the other.The child process is an exact duplicate of the parent.

On success, the PID (process id) of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.

8. Exucting the command.

Now that we have the child process (a copy of the shell at this moment). The computer has the green light to run the command. We use the execve() function for this purpose. execve() executes the program pointed to by filename. filename must be either a binary executable.

execve() does not return on success, and the text, data, bss, and stack of the calling process are overwritten by that of the program loaded (now the child process isn’t a copy of the shell anymore, the command ls -l has been executed into that child process)

Tadaa by this time the command has been executed successfully and you should see in the screen something like this:

9. Clean everything

Remember the getline() and strtok() functions ? we occupied some memory that we don’t need anymore. So we have to use free() to release it and the system can use that resources in something else.

10. Start again.

If the command isn’t exit, and we were working in the interactive mode, we show the prompt again and the process restart.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *