Собственный шелл (Написать собственный шелл под ОС Unix, подобный bash)
Модератор: Модераторы разделов
-
chuguvik
- Сообщения: 5
- ОС: Windows 7, Free BSD 7.2
Собственный шелл
Здравствуйте!
Нужно сделать шелл на языке Си под ОС Unix, реализовывая команды: конвейер(через |), последовательное выполнение команд(через , выполнение команды при удачном выполнении предыдущей (&&) и при неудачном (||). Подача происходит либо из командного файла, либо с ручного ввода. В общем, с потока stdin либо любого другого FILE * stream
Суть моего вопроса в том, как заставить работать, то есть организовать связь между командами и процессами, после разбивки строки?
К примеру, есть входная строка:
(ls -R dir1| grep 'mydir1'; (pwd;cd..;pwd) | sort) |wc
Я могу её разбить на команды, то есть получить строки, содержащие команды:
ls -R dir1
grep 'mydir1'
pwd
cd
pwd
sort
wc
..и на разделители:
(
|
;
(
;
;
)
|
)
|
Также есть приоритеты операций(возрастание сверху вниз):
1. (
2. || , &&
3. &, ;
4. |
5. < , >>, >
Я не могу понять, как связать эти команды в единую цепочку и как в правильной последовательности исполнять это. Пробовал делать при помощи польско-инверсной записи - не получилось.. То есть мне нужна идея состоящая в том, как сделать из этого списка команд и разделителей единый список/массив, который можно будет запустить на исполнение, а также понять как его обрабатывать.
Нужно сделать шелл на языке Си под ОС Unix, реализовывая команды: конвейер(через |), последовательное выполнение команд(через , выполнение команды при удачном выполнении предыдущей (&&) и при неудачном (||). Подача происходит либо из командного файла, либо с ручного ввода. В общем, с потока stdin либо любого другого FILE * stream
Суть моего вопроса в том, как заставить работать, то есть организовать связь между командами и процессами, после разбивки строки?
К примеру, есть входная строка:
(ls -R dir1| grep 'mydir1'; (pwd;cd..;pwd) | sort) |wc
Я могу её разбить на команды, то есть получить строки, содержащие команды:
ls -R dir1
grep 'mydir1'
pwd
cd
pwd
sort
wc
..и на разделители:
(
|
;
(
;
;
)
|
)
|
Также есть приоритеты операций(возрастание сверху вниз):
1. (
2. || , &&
3. &, ;
4. |
5. < , >>, >
Я не могу понять, как связать эти команды в единую цепочку и как в правильной последовательности исполнять это. Пробовал делать при помощи польско-инверсной записи - не получилось.. То есть мне нужна идея состоящая в том, как сделать из этого списка команд и разделителей единый список/массив, который можно будет запустить на исполнение, а также понять как его обрабатывать.
-
/dev/random
- Администратор
- Сообщения: 5497
- ОС: Gentoo
Re: Собственный шелл
i Уведомление от модератора Тема перемещена из раздела "Работа в командной строке" в раздел "Программирование".
Дубль этой темы в разделе "Программы" удалён.
Автору делается официальное предупреждение за кросспостинг.
Оффтоп о том, что автор нарушил правила, удалён.
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Собственный шелл
Нечто аналогичное тут пробегало: Передача функции через строку
Можете взять тот мой код за основу и переделать под Ваши реалии.
Можете взять тот мой код за основу и переделать под Ваши реалии.
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
-
chuguvik
- Сообщения: 5
- ОС: Windows 7, Free BSD 7.2
Re: Собственный шелл
а как "заглянуть" в код bash? Где это находится? Вроде в /bin имеется только исполняемый файл с именем bash, а кода там нет. Если я что-то путаю, подскажите
-
chuguvik
- Сообщения: 5
- ОС: Windows 7, Free BSD 7.2
Re: Собственный шелл
NickLion писал(а): ↑29.11.2009 20:48Нечто аналогичное тут пробегало: Передача функции через строку
Можете взять тот мой код за основу и переделать под Ваши реалии.
Посмотрел по ссылке. Но это же не калькулятор, где нужно делать при поступлении новой операции все предыдущие с большим приоритетом. Здесь нечто другое..Эту идею я пытался как-то применить к моей задаче, реализовывал список операций и список команд. Не помогло и ещё больше запутался..
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Собственный шелл
http://ftp.gnu.org/gnu/bash/bash-4.0.tar.gz
Там же есть и более ранние версии bash, в которых поменьше кода и разобратся в которых, думаю, будет немного проще.
-
Portnov
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: Собственный шелл
Я бы советовал не bash, а что-нить попроще - dash, например.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
chuguvik
- Сообщения: 5
- ОС: Windows 7, Free BSD 7.2
Re: Собственный шелл
спасибо!
Попробую последовать Вашему совету!
Попробую последовать Вашему совету!
-
chuguvik
- Сообщения: 5
- ОС: Windows 7, Free BSD 7.2
Re: Собственный шелл
эх..Ну и код там..Я, чувствую, совсем ещё новичок в этом..Даже dash не очень понимаю. И всё-таки, можете подсказать саму идею? Написать-то сам смогу, мне бы лишь идею узнать..
-
Crazy
- Сообщения: 862
- Статус: Адепт Дзен.
- ОС: Mint, Win7.
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Собственный шелл
Реализаций в принципе может быть много... Думаю, вам очень поможет эта книжка: Альфред Ахо, Рави Сети, Джеффри Ульман "Компиляторы. Принципы, технологии, инструменты" - довольно подробно рассмотрен синтаксический и лексический анализ, в общем, советую.
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Собственный шелл
chuguvik писал(а): ↑29.11.2009 21:44Посмотрел по ссылке. Но это же не калькулятор, где нужно делать при поступлении новой операции все предыдущие с большим приоритетом. Здесь нечто другое..Эту идею я пытался как-то применить к моей задаче, реализовывал список операций и список команд. Не помогло и ещё больше запутался..
На самом деле отличия от калькулятора немного. Тот калькулятор вычисляет строковые выражения вида: ((x+y)*6-z)*pow(18,0.5) - вычисления идут в соответствии с приоритетом. В вашем случае тоже есть строка, тоже приоритет. Только операции другие и форма записи несколько отличается. А в целом можно рассматривать как калькулятор выражений.
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Собственный шелл
NickLion писал(а): ↑30.11.2009 06:17На самом деле отличия от калькулятора немного. Тот калькулятор вычисляет строковые выражения вида: ((x+y)*6-z)*pow(18,0.5) - вычисления идут в соответствии с приоритетом. В вашем случае тоже есть строка, тоже приоритет. Только операции другие и форма записи несколько отличается. А в целом можно рассматривать как калькулятор выражений.
Разница хоть на первый взгляд незначительная, но она есть - калькулятор оперирует постоянным выражением (т.е. достаточно создать дерево разбора), в случае же shell'а нужно будет создавать какое-то подобие таблицы символов (для функций и переменных), разворачивать при необходимости выражения, т.е. осуществлять полноценный лексический и синтаксический анализ, так что я совсем не завидую топикстартеру =)
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Собственный шелл
RasenHerz писал(а): ↑30.11.2009 07:12Разница хоть на первый взгляд незначительная, но она есть - калькулятор оперирует постоянным выражением (т.е. достаточно создать дерево разбора), в случае же shell'а нужно будет создавать какое-то подобие таблицы символов (для функций и переменных), разворачивать при необходимости выражения, т.е. осуществлять полноценный лексический и синтаксический анализ, так что я совсем не завидую топикстартеру =)
В том коде поддерживались переменные, функции. Т.е. один раз строится дерево, и можно его вычислять много раз для разных значений переменных. То, что задача у ТС более сложная - не спорю. Особенно что касается самого разбора выражения. Но если ТС не представляет как делать данную задачу, то лучше разобраться с более простой подобной. Прикрутить ленивые вычисления. А там уже и перестроить под исходную задачу проще будет. Или заново написать, но уже со сложившейся схемой в голове.
-
BlackStar
- Сообщения: 1338
- Статус: We are all Kosh
- ОС: Fedora 10
Re: Собственный шелл
В книге "Unix/Linux Теория и практика программирования, Брюс Моли" подробно описан процесс создания простого шелла.
Схема следующая:
Схема следующая:
Код: Выделить всё
| write |---| read |---| fork |---| wait |-----------------------| |
|
| |---| exec |---| main |---|exit|/LightLang Team
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Собственный шелл
BlackStar писал(а): ↑30.11.2009 11:57В книге "Unix/Linux Теория и практика программирования, Брюс Моли" подробно описан процесс создания простого шелла.
Схема следующая:
Код: Выделить всё
| write |---| read |---| fork |---| wait |-----------------------| | | | |---| exec |---| main |---|exit|/
Ну это поможет создать конвейер, и начать исполнение программы, но до более-менее функционального шелла этой схеме как до Китая пешком =)
-
serzh-z
- Бывший модератор
- Сообщения: 8259
- Статус: Маньяк
- ОС: Arch, Fedora, Ubuntu
Re: Собственный шелл
chuguvik
См. книгу: Разработка приложений в среде Linux. Майкл К. Джонсон, Эрик В. Троан. Вильямс. ISBN 978-5-8459-1143-8. Очень рекомендую. В частности, начиная с раздела 10.7 (во втором издании, 2007 г.), всё рассказывается на примере разработки простой оболочки ldash, которая по ходу книги и разрабатывается.
См. книгу: Разработка приложений в среде Linux. Майкл К. Джонсон, Эрик В. Троан. Вильямс. ISBN 978-5-8459-1143-8. Очень рекомендую. В частности, начиная с раздела 10.7 (во втором издании, 2007 г.), всё рассказывается на примере разработки простой оболочки ldash, которая по ходу книги и разрабатывается.