Pull to refresh

Comments 107

Простите, но тролейбус.jpg
Для каждого языка есть свое место применения. На perl можно написать 3D игру, только зачем?
Не являюсь поклонником PHP, но хотелось бы вспомнить про язык JavaScript. Его применение в прежние годы было крайне ограниченно. А вот что этот язык перерос сейчас? Еще стоит упомянуть ActionScript. Помните те годы, когда AS был языком, позволяющим самую малость добавить интерактивности в flash компоненты? А сейчас на нем пишут enterprise приложения. Т.ч. время меняет представление о «применении» той или иной технологии/языка.
Ваша точка зрения понятна, но хочется заметить вот что — такое «превращение» и перенацеливание ActionScript вызвано в том числе и стремительным развитием самого ActionScript.
AS1 и AS3 (последний актуальный) — это два совершенно разных языка, код на одном не компилируется в другом. В AS3 теперь есть строгая (в основном статическая) типизация, появились классы и интерфейсы, есть даже геттеры — он больше похож на Java, а не на JS, как AS1.

Без всякого сарказма или потаённого смысла, было бы очень интересно посмотреть на то, как в этом отношении развивался php
habrahabr.ru/blogs/php/136800/

Ну вот, можете посмотреть здесь. PHP тоже развивается и обзаводится новыми полезными качествами. Взрослеет, в общем. В том числе, есть и движение к более строгой типизации.
возьмите и посмотрите, на сайте все есть у РНР. Он мало чем (на самом деле, не могу придумать даже чем) отличаеться от других языков. И есть у меня вся веб-система на РНР, зачем выносить какую-то одну процедуру и городить зачастую огород из RPC (между двух платформ) чтобы воспользоваться уже существующим кодом
Активно минусующие прояснят свою позицию?
Назовите, пожалуйста, хотя бы некоторые из серьезных причин, по которым PHP не следовало бы использовать для написания консольных утилит.
Пожалуйста, автор сам ее озвучил — скорость работы. Я, например, для парсинга большого текстового файла возьму что-то другое.
Для мелких прикладных задач вполне возможно использовать PHP, тут сомнений и возражений нет.
В том же Badoo консольные утилиты пишутся на PHP просто потому, что почти весь сайт написан на PHP, и засчет того, что консольные приложения тоже пишутся на PHP, мы используем большую часть существующего и отлаженного кода, вместо того, чтобы писать его заново. Этот же факт помогает исключить дублирование кода и поддержание нескольких реализаций на разных языках.
+100500, делаем так же, пачки кронджобов на php, которые реюзаюя классы с сайта, выполняют различные обновления, парсят xml данные, генерят картинки и т.п.
У меня тоже самое что и у вас, только я использую Yii у которого есть CConsoleApplication и CConsoleCommand — это позволяет мне писать код не думая о том, WEB у меня или консоль (естественно за исключением очевидных вещей, что у консольного могут быть параметры, а на WEB приходят GET/POST/etc). Крайне удобно и кодовая база идентична (модели, компоненты, модули, поведения).
А если вся компания на PHP пишет? У Фликр, например, есть PHP-сервисы для работы с фото, которые сжимают фото, ресайзят, складывают как надо и т.д. Зачем мне что-то другое, если меня устраивает скорость и я могу написать PHP скрипт (да еще и учитывая, что у меня уже есть кодвая база на нем) в разы быстрее, чем Java или C++, например?
Скорость работы это еще не показатель. Сомневаюсь, что пара лишних секунд работы скрипта так уж критична, зато скорость написания и отладка на php значительно быстрее, чем на том же Си.
Согласен что скорость штатных функций работы с текстом у PHP может уступать нативному, допустим, grep-у в Linux, но не всегда это основополагающий фактор, из-за которого стоит отвергнуть на корню вообще идею использования PHP для консольных приложений. Доводы, приведенные выше, в особенности уже существующий код проектов, связанных с будущей утилиткой на PHP, который можно повторно использовать, на мой взгляд, более существенны, если речь не идет, конечно же, о какой-то задаче, требующей реально высокой скорости обработки.
единственная причина, по которой я пишу мелкие прикладные скрипты на РНР — все коллеги знают этот язык. Задачи парсинга файлов значительно проще и быстрее делаются на Перле, очень многие задачи можно сделать даже на шелле.
РНР из коробки весьма беден функциями, нужными сисадмину, я это по своему опыту пишу.
Позвольте не согласиться.

Что именно из коробки в ПХП (PHP CLI)
не хватает в отличии от перла? Навскидку могу вспомнить только многопоточность.
например, парсинг тем писем в необработанных почтовых сообщениях. Правда, я в последнее время обычно питон для этого использую. А что касается перла, то в нём удобно текст разбирать. Например, мой скрипт для парсинга конфигов (вырезает комментарии):
#!/usr/bin/perl
while (<>)
{ chomp;
s/^\s//;
next if /^#/;
next if /^$/;
print "$_\n";
}

А представьте как он будет выглядеть на РНР?
Так и хочется сказать, что будет выглядеть читабельно :). Я вот хоть и немного знаю Perl, но мне пришлось немного подумать, чтобы понять, что делает ваш скрипт :).

#!/usr/bin/env php
<?php
while(false !== ($ln=fgets(STDIN))) { // while(<>) короче, согласен :))
$ln = trim($ln);
if(!strlen($ln)) continue;
if($ln[0]=='#') continue;
echo "$ln\n";
}


Вывод, вроде как, одинаков (я, кстати, исправил заодно ошибку с тем, что вы только один пробел в начале вырезаете :)):

$ cat test.txt
Hello

# comment
Just test
a
0

Hello world
$ cat test.txt | ./skip_comments.pl
Hello
Just test
a
0
Hello world
$ cat test.txt | ./skip_comments.php
Hello
Just test
a
0
Hello world
Кстати говоря, я не утверждаю, что скрипт на PHP меньше:
PHP-скрипт весит 197B, Perl-скрипт весит 89B
Кстати, это я посчитал длину файла с комментарием на русском языке :). Если без моего комментария, то получается, что скрипт на PHP весит 149B
и всё-таки чисто субъективно код на Перле выглядит изящнее. Особенно если использовать регулярные выражения по назначению, а не для сокращения кода, как я в этом случае.
Про ошибку интересно подметили.
Регулярные выражения — это нечитабельный код прежде всего. Поэтому меня совершенно не расстроило, что PHP весит 149 байт, зато я прочесть и понять его смог сразу же.
Вы же говорили, что вам чего-то в пхп не хватает из коробки, а в итоге говорите об изящности кода.

Практика показывает, что осуждающие PHP и хвалящие Perl в 90% просто не знают, как сделать то, что они хотели в этом языке, т.к. почти всегда это можно сделать почти так же, но удобнее конечно думать, что перл особенный, в нем можно, а в PHP — нет (или надо что-то доставлять).
я не говорил, что Перл из коробки богаче РНР. Кроме того, я использую не только Перл, но и Питон.
Аргумент про не знают просто не катит, т.к. выше я написал, что сейчас делаю всё на РНР, потому что коллеги только его знают.
Я достаточно знаю Перл, РНР и немного Питон, чтобы делать свой выбор. А недостаточное знание другими РНР-программистами Перла совсем не говорит о том, что РНР лучше для конкретных задач.
Я понял, чего мне нехватает в РНР: быстрого старта. Когда пишешь консольное приложение на РНР, надо предусмотреть вывод ошибок на экран на время отладки (в других языках это сразу работает, а РНР обычно пишет в error_log, который еще найти надо). Надо проверить, чтобы cgi-версия РНР вообще была, а не только модуль апача. Вызов сторонних приложений из РНР сделан через жопу, о чём даже в этом топике говорится. Использование регулярных выражений в Перле удобнее, ну а если кому-то не не нравится — пусть пишут свои парсеры. Многие перечисленные нюансы возникают от того, что РНР создавался как язык для веба, а не универсальный для всего, и глупо отрицать это наследие.
PS: в дальнейшем споре я не буду участвовать из-за системы оценок, но почитаю.
У нас например некоторым крон-скриптам можно передать флаги. Например:
--force -f форсировать генерацию данных, даже если они уже есть
--ignore-lock — игнорировать лок скрипта, если такой же уже выполняется (у нас часто скрипт не может запуститься, если уже выполняется такой же)
--print-output — тут понятно
если скрипт работает с большим ассивом данных, можно пердавать ему то сколько элементов нужно обработать флагом --limit -l
и т.д.

Можно использоваться как консольные интерфейсы для существующего софта… Применений много.
UFO landed and left these words here
Да, как писал youROCK выше, в этом и преимущество, не нужно дублировать код.

Единственное что нужно помнить что у вас нету таких переменных как $_GET, $_POST, $_COOKIE, а $_SERVER отличается по содержимому. Но появляются как getopt(), $argv, и $argc чтобы работать с переданными параметрами
Даже добавлю некоторые фраймворки имеют встроенную поддрежку из браузера и консоли.
Например в CodeIgniter есть рассширешие CLI и тогда то что у вас в урле как

yourdomain.com/module/controller/action/param1/param2/param3/…

можно запустить вот так

$php index.php module controller action param1 param2 param3…

Только надо следить за выводом и не выдать кучу HTML кода в Консоль.
да и в zf есть. Я думаю эта фича есть почти во всех фреймворках.
На упомянутом Perl отлично пишутся мелкие мультиплатформенные парсеры, как в прочем и на php. Perl зато с помощью PerlApp можно загнать в snandalode exe и дать человеку у которого перла нет
perl? а еще есть python, на нем тоже очень спокойно пишутся парсеры веб страничек, и его можно загнать в приложение (даже несколькими способами вроде).
позвольте не согласиться. зачастую консольные приложения на пхп — это всякие кроны, которые обслуживают основной проект. это импорт всяких внешних данных, сборка javascript'ов и css, очистка всяких фаловых кешей, генерация каких-то кешей заново, рассылка почты и прочее. если у меня есть большой проект со сложной структурой и мне надо раз в сутки стягивать обновление данных из внешних источников — вы прикажете мне писать на Си или перле заново все модели? но моделями ведь приложение не ограничивается и потому мне надо еще и управляющую логику нарисовать. и тоже на каком-то другом языке. но зачем, если существует уже работающий моторчик, в котором работы-то — всего-лишь докрутить запуск оного из консольки. да, быстродействие страдает. но процессорное время дешевле времени программистов и дешевле времени в бизнесе.
на php тоже можно написать 3D игру.
Не могли бы вы подробнее описать обработку пользовательского ввода в процессе выполнения скрипта?
Это опции запуска. Я имел в виду пользовательский ввод во время выполнения скрипта: чтение из stdin, ввод данных с возможностью редактирования, ожидание нажатия клавиши (например y/n или стрелки вверх) и т.д.
Ну, для большинства задач fgets(STDIN) хватает за глаза ;)
Вот функция, которая у нас используется и отлично работает:
function askValue()
{
    $stream = fopen('php://stdin', 'r');

    return trim(fgets($stream));
}
Конечно, да.

Только вот не надо забывать про замечание:
Эти константы недоступны, если PHP считывает запускаемый скрипт из stdin.

В моём случае обычно так и получается и эти константы мне не доступны.
Если PHP считывает запускаемый скрипт из stdin, тогда попросить пользователя ввести что-либо тоже не получится ;), ибо в STDIN поступает текст исполняемой программы
Хм… тогда странно, что скрипт отрабатывает, но у меня нет этих констант.
Может подскажете?

grevus@grevus ~ $ php -v
PHP 5.3.9 with Suhosin-Patch (cli) (built: Jan 11 2012 10:25:51)


Выполнение скрипта:
php projects/common/auto/runner/run.php some_our_script.php
«Скрипт поступает из STDIN» означает, что вы запускаете следующим образом:
php <projects/common/auto/runner/run.php (обратите внимание на "<" :))
Если вы запускаете не через STDIN и у вас этих констант нет, значит это баг, и в этом отдельном случае нужно разбираться более детально.
я идиот, простите :(
Вы были правы.
Я не правильно проверял :(
Спасибо. Однако, при таком чтении не получается отредактировать строку с помощтю стрелок во время ввода (хотя она приходит отредактированной). Получается как-то так: abc^[[D^[[Dde, что не всегда удобно.
Спасибо, это то, что нужно!
Жаль только, что расширение не работает на Windows.
Консольные скрипты для винды с юзерским вводом из консоли? О_О
У меня велосипед для этих целей есть. Век живи — век луркай. Спасибо.
для а-ля консоль рекомендую использовать readline расширение которое идёт по умолчанию в PHP. или же STDIN константу, которая ресура, на самом деле.
Огромное спасибо.
Давно хотел что-то эдакое попробовать.
Но есть пара вопросов:
1. На сколько я знаю, в *nix и MacOS php встроенный. А в Windows разве встроенный?
2. Может вы знаете какие-то хитрые тулзы, при помощи которых можно обернуть php в gui?
1. В Linux обычно PHP из коробки нет. В Mac OS X есть, в Windows тоже нет.
2. php-gtk разве что :). Но лучше их не использовать, ИМХО
1. Совсем беда. Т.е. еще нужно заставить юзера поставить php…
2. А почему лучше не испоьзовать?
О, оказывается есть и php-qt!
2. PHPDock, например.
В качестве UI — страница, отображаемая в интегрированном браузере.
интересная штука, спасибо, но windows-only (
Отличная статья, в свое время тоже до всего доходил самостоятельно.

Хотелось бы коснуться темы сокетов — был опыт работы с ними? Вы пишите, что перед fork'ами надо все ресурсы закрывать, что невозможно сделать когда, например, у нас есть сервер, который всегда ждет входных данных на свой порт, а все полученные запросы к нему раскидывает по дочерним воркерам.

Как показали эксперименты, связка socket_create/socket_bind очень сильно ела память, стал использовать stream_socket_server, память течет значительно меньше, но течет. Помогают перезапуски сервера. Как я выявил, проблема в закрытии ресурса после вызова stream_socket_accept из сервера-родителя.

Был ли такой опыт и как вы это бороли? :)
Если вы пишете свой апач, то, конечно, без этого вы обойтись не сможете :). Я честно скажу — я не помню, как я решал проблемы с утечкой памяти при работе с сокетами, когда писал что-то аналогичное :). По-моему, у меня таких проблем вообще не было.
Спасибо за ответ.

Я сам эту проблему заметил не сразу, после активной работы демона в течение месяца увидел, что тот отъел порядка 100 лишних мб памяти.
Тут же был написан брут-скрипт, который в 3х запущенных вариантах набирал на сервере порядка 500 лишних мб за 5 минут, вот и висит вопрос с тех пор :)
Я не вижу проблемы с авто-перезапуском каждые 10000 запросов, как умеет тот же апач :)
Решал проблему аналогично, только через проверку занятой памяти. memory_get_usage Как только съел больше определенного порога — перезапуск
так опасно, уж лучше совместно со счетчиком запросов, всё-таки нужна какая-то граница снизу.
У меня был *nix service реализованный который из мониторил сокет и писал в базу.
Открывал соеденение через сокет к IBM Webshere и ждал запись. Как только, что-то приходило писал в базу запрос. Тек как разтаки модуль для php-cgi от IBM ;( они видилите его с 2007 для ПХП больше не поддерживают. Поэтому у меня память убегала быстрее чем все мыслеммые счетчики, даже на 1000-10000 запросов :))

Правада в итоге мы выбили С код для модуля и его фиксили.
Память по идее должна убегать условно-линейно с ростом счётчика. Иначе по закону сохранения получается, что она убегает даже в том случае, если в сокете ничего нет и никогда не будет. Так написать — надо очень постараться.
Почти. Скажем так я читаю из сокета строку типа JSON и которая прогонялась через внутрений билдер и создавала объект (что-то похожее на PDOStatement после запроса)

Так проблема была, что даже после unset объект криво удалялся из памяти, а объект был не всегда одиканого размера :( где-то внутри открытого соеденения оставались ссылки на него.

П.С. это был мой первый опыт написания php-cgi / php-cli скрипта который должен был больше чем Крон и быть с максимальным аптаймом. Так что я там много дров наломал и граблей насобирал. На избушку точно хватит :)
Но ведь то, что не удалялись ссылки — это как раз и есть причина утечек памяти. А если в сокете ничего нет — то и память не течёт. Значит, мы выбираем память условно-пропорционально числу запросов (с поправкой как раз на «не всегда одинакового размера»).
а чем счетчик будет лучше чем наблюдением за паматью.
Я знаю сколько могу занять Х. знаю сколько уже занял памяти Y. и если
Y/X < скажем 90% то все ок.
Чем такой вариант хуже? Особенно при условии что мне скрипт должен быть все время запущен. Или просто как второй критерий проверки и защиты?
Кстати, после того, как код был уже написан и прошли набитые шишки, из недр гугла удалось достать библиотеку (phpsocketdaemon), которая имеет очень положительные отзывы в плане работы с памятью.

Может кому пригодиться, а может у кого уже был опыт использования?
был, да и на хабре были статьи о нем, почитайте.
мы не форкались, но активно использовали сокеты. как показал наш опыт — утечки связаны с кодом, а не с языком — наверняка есть циклические ссылки, например.
совет по отлову — логируйте сколько было памяти до обработки запроса и после. если дельта больше нуля — смотрите всю цепочку обработки, удаляйте не нужные объекты, избавляйтесь от циклических ссылок. особое внимание — foreach'ам с объектами.
#! — называет шибэнг.

непонятно зачем использовать php, если есть bash для этих целей. Особенно exec и system, которые по-хорошему нужно запретить использовать.
Думаю, вы не совсем поняли сочетание «PHP CLI» в названии топика.

1. Основной плюс PHP CLI — работа с объектами (моделями) уже описанные в самом проекте, без написания уже существующего функционала, следовательно экономим время на разработке.

2. Bash врядли сможет легко манипулировать данными как в базе, так и в nosql демонах (memcached/mongo/redis). А вызов system в php cli зачастую необходим только для того, чтобы сделать ротацию логов, сделать ресайз нескольких фотографий, ну и удалить какой-то мусор.
> 1. Основной плюс PHP CLI — работа с объектами (моделями) уже описанные в самом проекте, без написания уже существующего функционала, следовательно экономим время на разработке.

никогда не приходилось использовать никаких моделей в скриптах. Все что запускалось по крону работало напрямую с БД

> 2. Bash врядли сможет легко манипулировать данными как в базе, так и в nosql демонах (memcached/mongo/redis). А вызов system в php cli зачастую необходим только для того, чтобы сделать ротацию логов, сделать ресайз нескольких фотографий, ну и удалить какой-то мусор.

с mysql/pgsql никаких проблем не возникало. Для memcached:

echo «stats» | nc 127.0.0.1 11211

> никогда не приходилось использовать никаких моделей в скриптах.
вам не приходилось. мне приходилось. это вопрос личного опыта, а не аргумент.

> с mysql/pgsql никаких проблем не возникало.
так зачем же вы писали скрипт на php, который работает с базой, если одними и теми же данными может с успехом манипулировать и bash?
> так зачем же вы писали скрипт на php, который работает с базой, если одними и теми же данными может с успехом манипулировать и bash?

у меня есть системные CGI скрипты на bash/awk, которые выводят статистику по БД, на php я не пишу. Все либо FCGI на C, либо WSGI на Python. Как только FCGI реализуют на bash, обязательно перейду на него.
Было бы неплохо осветить работу с расширением readline, многим было бы интересно.
Я могу понять CLI-скрипт на PHP в том случае, если у вас есть какой-нибудь сложный веб-проект на PHP с уже готовой объектной моделью, с которой надо работать.

Я могу понять, если человек просто не знает (или знает недостаточно хорошо) другие скриптовые языки, вроде перла или питона, и есть какая-нибудь несерьезная или учебная задачка.

Во всех же остальных случаях… ну, это все равно что какать на улице при людях — вроде бы и покакали (решили задачу), но ни вам, ни окружающим удовольствия это не принесло. Ну если только что вы большой шутник да затейник.
А если без туалетных метафор, чем PHP хуже перла или питона?
Да на нем же одна школота пишет! *sarcasm*
PHP достаточно универсален, чтобы на нем можно было написать все, что можно написать на Perl, Python, bash, whatever.

Но видите ли в чем дело, PHP не предназначен для того, чтобы писать на нем системные утилиты. Это доказывает хотя бы эта вот статья. Согласитесь, что если бы вы писали на bash, вам бы не пришлось указывать на тонкости рекурсивного удаления директории или запуска другой программы и получения данных от нее, не так ли?

Используйте язык для решения тех задач, для которых он разрабатывался, а если перед вами стоит задача из другой области — воспользуйтесь другим.
> Согласитесь, что если бы вы писали на bash, вам бы не пришлось указывать на тонкости рекурсивного удаления директории или запуска другой программы и получения данных от нее, не так ли?

Согласитесь, что если бы вы писали на bash, вам бы пришлось указывать на тонкости выборки из БД, кэширования, объектной модели, существующего кода etc.
Я вижу, вы уловили суть — использовать тот язык программирования, который предназначен для решения стоящей перед вами задачи, а не тот, который вы знаете или который вам нравится.
И использовать 10 языков вместо одного? Нет, понятно, иногда есть явные ограничения языка (скорость, возможности работы с памятью, многопоточность), которые заставляют писать на чем-то другом. А тут то что не так? php вполне нормально работает в качестве средства для написания консольных утилит. Особенно, если есть подходящее окружение (framework).
Писать на перле и питоне только потому, что в айтишной тусовке их считают более крутыми? Нормально для вспыльчивого студента, не более.
Для начала, давайте вы не будете заниматься демагогией и приписывать мне высказывания, которых я не говорил (я про крутость языков).

Затем, насчет «вполне нормально работает» — возможно, если бы он просто нормально работал, не было бы необходимости в этой статье, разве нет?

А это коварное «вполне» впоследствии может вылиться в большие проблемы, как по времени, так и по деньгам — я, например, сталкивался.

Вы сталкивались с кривыми руками (если были проблемы конкретно с cli на php). php позволяет писать криво, это его проблема. Но только для тех, кто пишет криво. Грамотно он тоже позволяет делать.

Касательно того, зачем статья — в учебниках по Си подобные вещи тоже описывают. Они элементарны, в основном, просто почему-то в учебниках по php это обходится стороной, обычно. Но ничего необычного или сложного в этой статье не описывается, подобным образом работают и на других языках консольные программы.
Единственный описанный ньюанс — реализация system, остальное — практически цитаты из учебника.
Да ладно, каждый работает с чем умеет. Вон у Zeus'а makefile был php написан :)
Консоль forever!

Спасибо, определенно полезная статья с учетом того что часто проще написать консольную утилиту на более медленном языке, чем посвящать разработчика на другом языке во всю архитектуру существующего веб-приложения.
А почему не воспользоваться PHP_EOL вместо \n?
По-моему, echo "Hello world\n"; в Windows тоже работает, а для всех остальных ОС (в том числе Mac OS X) строки итак заканчиваются на "\n" по умолчанию. Поэтому я не вижу смысла в использовании PHP_EOL конкретно в этом месте :)
Нет. В MacOS 9 и ниже — действительно "\r", поскольку MacOS 9 — это не *nix. Как подсказывает вики (http://en.wikipedia.org/wiki/MacOS), последняя версия классической MacOS была выпущена более 10 лет назад (в 2001 году).
Так а зачем разбираться в этих тонкостях, если PHP_EOL предназначена именно для решения этих вопросов? А если завтра появится новая ОС и в ней будет другой символ для перевода строки?
Да нет здесь никаких тонкостей :). Сейчас \n работает везде, и я не вижу причин, почему кто-то в обозримом будущем будет создавать ОС, где перевод строки — это что-то ещё.
Правильное предложение, на мой взгляд.
// не забывайте \n на конце
echo "Usage: ".$argv[0]." \n";
А мне нравится так писать:
echo "Usage: {$argv[0]} ", PHP_EOL;
Хотя это не принципиально.

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

2>&1 использую для вывода ошибок в стандартный поток, когда по ssh команду какую-нить у другого сервера прошу выполнить, иначе ошибок при выполнении команды на удалённом сервере не видать.
Ой, че-то с тэгами накосячил, всё как код теперь :(
кстати, всегда думал, что на «неправильные аргументы командной строки», принято возвращать все-таки двойку:
$ ls -z; echo $?
ls: invalid option -- 'z'
Try `ls --help' for more information.
2

хотя, традиция — не закон.
$ ls --afdafdsaf
ls: illegal option — -
usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file ...]
$ echo $?
1
Пример в linux:

$ git dfadsfdsf
git: 'dfadsfdsf' is not a git command. See 'git --help'.
$ echo $?
1
$ cp --afdfadfa adfadsaf
cp: ключ --afdfadfa не распознан
Попробуйте `cp --help' для получения более подробного описания.
$ echo $?
1
вполне годные можно скрипты писать на bash с применением всех консольных утилит
Only those users with full accounts are able to leave comments. Log in, please.