bash — вопросы с ответами

12 ответов
Я установил Laravel с помощью композитора без проблем, но когда я пытаюсь выполнить "laravel" в моем терминале, у меня есть эта типичная ошибка: - bash: laravel: команда не найдена Если я прочитал документацию на официальном сайте, мне нужно сделать это: Обязательно поместите каталог ~/.composer/...
15 окт. 2014, в 07:53
20 ответов
Я нахожусь на Ubuntu 14.04 и пытаюсь всеми возможными способами установить Laravel безрезультатно. Сообщения об ошибках все, что я пытаюсь. Сейчас я пробую первый метод в документации по ~/.composer/vendor/bin, то есть через установщик Laravel, но он говорит: "Убедитесь, что вы ~/.composer/vendor/b...
path
.bash-profile
18 авг. 2014, в 21:57
18 ответов
В Bash, попробовал следующее: echo -e "hello\nworld" Но он не печатает новую строку, только \n. Как я могу сделать печать новой строки? Я использую Ubuntu 11.04.
echo
newline
11 дек. 2011, в 19:11
23 ответа
Я пытаюсь напечатать текст в терминале с помощью команды echo. Я хочу напечатать текст красного цвета. Как я могу это сделать?
echo
command-line
10 май 2011, в 09:52
28 ответов
В PHP строки объединяются следующим образом: $foo = "Hello"; $foo .= " World"; Здесь $foo становится "Hello World". Как это достигается в Bash?
append
syntax
concat
string-concatenation
15 нояб. 2010, в 05:04
42 ответа
У нас есть приложение PHP и мы хотим подсчитать все строки кода под определенным каталогом и его подкаталогами. Нам не нужно игнорировать комментарии, так как мы просто пытаемся получить приблизительную идею. wc -l *.php Эта команда отлично работает в пределах заданного каталога, но игнорирует под...
31 авг. 2009, в 17:36
36 ответов
Я хочу получить имя файла (без расширения) и расширение отдельно. Лучшее решение, которое я нашел, это: NAME='echo "$FILE" | cut -d'.' -f1' EXTENSION='echo "$FILE" | cut -d'.' -f2' Это неправильно, потому что не работает, если имя файла содержит несколько . персонажи. Если, скажем, у меня есть a...
string
filenames
08 июнь 2009, в 14:12
34 ответа
У меня есть эта строка, хранящаяся в переменной: IN="bla@some.com;john@home.com" Теперь я хотел бы разделить строки на разделитель ;, чтобы у меня было: ADDR1="bla@some.com" ADDR2="john@home.com" Мне необязательно нужны переменные ADDR1 и ADDR2. Если они являются элементами массива, которые еще лу...
scripting
28 май 2009, в 03:51
16 ответов
В оболочке Unix, если я хочу объединить stderr и stdout в поток stdout для дальнейшей обработки, я могу добавить следующее в конце моей команды: 2>&1 Итак, если я хочу использовать "head" на выходе из g++, я могу сделать что-то вроде этого: g++ lots_of_errors 2>&1 | head поэтому я в...
redirect
04 май 2009, в 00:14
17 ответов
Я использовал следующий script, чтобы увидеть, существует ли файл: #!/bin/bash FILE=$1 if [ -f $FILE ]; then echo "File $FILE exists." else echo "File $FILE does not exist." fi Какой правильный синтаксис использовать, если я только хочу проверить, существует ли файл не? #!/bin/bash FI...
scripting
file-io
12 март 2009, в 14:54
35 ответов
Как я могу проверить, существует ли программа, которая будет либо возвращать ошибку и выйти, либо продолжить с помощью script? Кажется, что это должно быть легко, но это меня колотило.
26 фев. 2009, в 22:33
30 ответов
Есть ли простой способ запустить MySQL-запрос из командной строки Linux и вывести результаты в формате CSV? Вот что я делаю сейчас: mysql -u uid -ppwd -D dbname << EOQ | sed -e 's/ /,/g' | tee list.csv select id, concat("\"",name,"\"") as name from students EOQ Это становится беспорядо...
csv
quotes
10 дек. 2008, в 16:49
22 ответа
У меня есть строка в Bash: string="My string" Как проверить, содержит ли она еще одну строку? if [ $string ?? 'foo' ]; then echo "It there!" fi Где ?? - мой неизвестный оператор. Использовать эхо и grep? if echo "$string" | grep 'foo'; then echo "It there!" fi Это выглядит немного неуклюжим....
string
substring
23 окт. 2008, в 14:20
32 ответа
Скажем, у меня есть script, который вызывается с помощью этой строки: ./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile или этот: ./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile Что принято в этом синтаксическом анализе, чтобы в каждом случае (или некоторая комбинация из дву...
scripting
arguments
command-line
getopts
10 окт. 2008, в 16:21
54 ответа
Как получить путь к каталогу, в котором находится Bash script, внутри которого script? Например, скажем, я хочу использовать Bash script в качестве запуска для другого приложения. Я хочу изменить рабочий каталог на тот, где находится Bash script, поэтому я могу работать с файлами в этом каталоге, на...
directory
12 сен. 2008, в 20:46

Подробнее о bash

Bourne-Again SHell (Bash) был разработан Фондом свободного программного обеспечения (FSF) в рамках проекта GNU, что придает ему несколько особую репутацию в сообществе открытого исходного кода. Сегодня Bash является пользовательской оболочкой по умолчанию в большинстве установок Linux. Хотя Bash является лишь одним из нескольких хорошо известных оболочек UNIX, его широкое распространение с Linux делает его важным инструментом, разбираться в котором приходится многим программистам.

Основная цель оболочки UNIX – позволить пользователям эффективно взаимодействовать с системой через командную строку. Обычная задача оболочки – вызвать исполняемый файл, что, в свою очередь, заставляет ядро ​​создавать новый запущенный процесс. Оболочки имеют механизмы для отправки результатов одной программы в качестве входных данных для другой и средства взаимодействия с файловой системой. Например, пользователь может просматривать файловую систему или направлять результат работы программы в файл.

Хотя Bash в первую очередь является интерпретатором команд, он также является языком программирования. Bash поддерживает переменные, функции и имеет конструкции потока управления, такие как условные операторы и циклы. Тем не менее все это идет с некоторыми необычными причудами. Это потому, что Bash пытается выполнять две роли одновременно: быть интерпретатором команд и языком программирования.

Все оболочки UNIX, включая Bash, являются в основном интерпретаторами команд. Эта характеристика имеет длинную историю, вплоть до самой первой оболочки и первой системы UNIX. Со временем оболочки UNIX приобрели возможности программирования путем эволюции, что привело к появлению некоторых необычных решений для среды программирования. Поскольку многие люди приходят в Bash, уже имея некоторый опыт работы с традиционными языками программирования, необычная перспектива, которую Bash использует в конструкциях программирования, вызывает много путаницы, о чем свидетельствуют многие вопросы, размещенные на форумах Bash.

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

Два в одном

Прародителем Bash была оригинальная оболочка Thompson shell, которая являлась простым интерпретатором команд, чей режим работы был следующим:

где command – это имя исполняемого файла (то есть команды, которая должна быть выполнена), и необязательные аргументы arg1 ... argN передаются команде. Оболочка Thompson shell сама по себе не имела возможностей программирования, но все изменилось с развитием оболочки Mashey shell (а позже и Bourne shell).

Фактически, именно оболочки Mashey и Bourne расширили возможности оболочки Thompson shell за пределы командного интерпретатора. Первоначальная роль оболочки была интерпретатором команд, а возможности программирования оболочек были добавлены позже. Оболочки UNIX развили несколько оригинальных способов объединения возможностей программирования с оригинальной ролью интерпретатора команд.

Принцип работы Bash

Сегодняшний Bash – это более мощный инструмент по сравнению с оригинальной оболочкой Mashey и Bourne. Однако назначение оболочки остается точно таким же. Возможно, самая важная функция оболочки – запуск команд (то есть передача исполняемого файла в ядро для выполнения). Она имеет несколько глубоких последствий. Для начала Bash рассматривает (почти) все, что ему дано, как команду. Давайте изучим следующую сессию Bash:

Это показывает, что Bash разбивает входной параметр на слова, а затем пытается выполнить первое слово в качестве команды ("слова" VAR и 9). Здесь "command" может быть встроенной командой Bash (например, cd), утилитой (такой как /bin/ls) или другим исполняемым файлом. Когда на входе была задана строка 9 + 1, Bash разделил ее на три "слова": 9, + и 1. Важно отметить, что Bash сохраняет все слова как строки и не имеет понятия о числах до тех пор, пока их не заставят выполнять арифметическую оценку. В довольно упрощенном виде Bash работает следующим образом:

  1. Берет ввод и разбивает его на слова с помощью пробелов (пробел или табуляция).
  2. Предполагается, что первое слово является командой. Если после первого слова что-то следует, предполагается, что оно является аргументом, который должен быть передан команде.
  3. Попытки выполнить команду (и передать ей аргументы, если таковые имеются).

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

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

Встроенные команды Bash против внешних

То, что часто сбивает с толку новичков в Bash, так это разница между встроенными командами Bash и внешними. В типичной системе Linux/UNIX часть общих команд встроены в Bash, а другая часть существует как независимые исполняемые файлы с одинаковыми именами. Примеры этого включают echo (встроенный) и /bin/echo, kill (встроенный), /bin/kill, test (встроенный) и /usr/bin/test. Рассмотрим, как встроенные echo и /bin/echo ведут себя очень похоже в Bash:

Однако есть и тонкие различия (попробуйте echo --version). Почему существует дублирование команд? На то есть несколько причин. Встроенная версия обычно существует по соображениям производительности: встроенные средства Bash выполняются в уже запущенном процессе оболочки. Напротив, выполнение внешней утилиты включает загрузку и выполнение внешнего двоичного файла ядром, что является гораздо более медленным процессом.

На этом этапе следует отметить, что некоторые команды оболочки по своей природе не могут быть внешними утилитами (другими словами, они должны быть встроенными в оболочку). Рассмотрим команду cd, которая изменяет текущий рабочий каталог. Внешняя утилита не сможет изменить текущий рабочий каталог оболочки, поэтому cd должен быть встроенным в Bash. Зачем? Потому что вызов команды в качестве внешней утилиты сделает оболочку ее родительским процессом, а дочерний процесс не сможет изменить текущий рабочий каталог родительского процесса.

Тут вы можете и спросить: «Если echo уже встроен в оболочку, почему существует внешняя утилита /bin/echo?» Это потому, что человек не всегда работает через оболочку и может нуждаться в вызове echo без посреднического процесса оболочки. Во-вторых, в принципе, нет ничего, что могло бы потребовать от UNIX-оболочки иметь echo как встроенную команду, и поэтому важно иметь внешнюю утилиту /bin echo на крайний случай.

Практическая проблема, с которой часто сталкиваются пользователи, заключается в следующем: откуда вы знаете, является ли только что вызванная вами команда встроенной в оболочку или внешней утилитой с тем же именем? Команда type в Bash (которая сама по себе является встроенной в оболочку) указывает, какая команда будет использоваться в случае ее выполнения. Например:

Основное правило таково: если встроенная команда с заданным именем существует, она будет выполнена. Если встроенной команды не существует, Bash будет искать внешнюю программу и, если она найдет ее, то сразу же выполнит. Если вы хотите быть уверены, что используете исполняемый файл, имя которого совпадает с именем встроенной оболочки, то вызовите исполняемый файл с указанием полного пути.

Назначение переменной

Когда команда вводится в Bash, Bash ожидает, что первое слово, которое он встречает, – это команда. Однако есть одно исключение: если первое слово содержит =, Bash попытается выполнить присвоение переменной. Например:

Это присвоило значение 7 переменной с именем VAR. Чтобы получить значение переменной, вам нужно добавить к имени переменной префикс со знаком доллара. Таким образом, чтобы просмотреть значение переменной, вы можете объединить префикс знака доллара с echo:

Для присвоения переменной важна непрерывная строка, содержащая =. Следующее команда будет неудачной:

В этом случае Bash разбивает входной VAR = 1 на три "слова" (VAR, = и 1) и затем пытается выполнить первое слово в качестве команды. Это явно не то, что здесь задумывалось.

Встроенная переменная ?

Хотя Bash позволяет создавать произвольные переменные на лету, просто присваивая им значения, он также имеет ряд встроенных переменных. Примером встроенной переменной является BASHPID. Он содержит идентификатор процесса самой оболочки Bash:

Еще одна встроенная переменная это знак вопроса – ?. В любой точке сеанса Bash эта переменная содержит возвращаемое значение последней выполненной команды. Возвращаемое значение всегда является целым числом. (и, в частности, это возвращаемое значение программной функции на C main(). Примечание: в любой программе на С функция main() должна возвращать целое число). По соглашению UNIX возвращаемое значение 0 обозначает успех, а любой другое значение означает сбой. Например, рассмотрим утилиту /bin/ls:

Согласно соглашению, утилита /bin/ls вернула 0 в случае успеха, что вы можете увидеть, проверив значение ?. Если ls не может быть выполнен (например, не может получить доступ к файлу), он возвращает значение >0:

В последнем примере обратите внимание, что первый ? был установлен на 2, а второй ? был установлен на 0. Почему? Потому что второй ? содержит состояние завершения команды echo (которая выполнена успешно). Помните, что переменная ? содержит состояние выхода последней выполненной команды. Вы можете использовать команды true и false, чтобы установить значение? на 0 или 1 соответственно:

Наверх
Меню