Статьи Язык shell

Discussion in 'Статьи' started by mR_LiNK[deface_0nl, 7 Jan 2007.

  1. mR_LiNK[deface_0nl

    mR_LiNK[deface_0nl Elder - Старейшина

    Joined:
    12 Dec 2006
    Messages:
    147
    Likes Received:
    27
    Reputations:
    13
    Командный язык shell (в переводе - раковина, скорлупа) фактически есть язык программирования очень высокого уровня. На этом языке пользователь осуществляет управление компьютером. Обычно, после входа в систему вы начинаете взаимодействовать с командной оболочкой (если угодно - она начинает взаимодействовать с вами). Признаком того, что оболочка (shell) готова к приему команд служит выдаваемый ею на экран промптер. В простейшем случае это один доллар ("$").

    Shell не является необходимым и единственным командным языком (хотя именно он стандартизован в рамках POSIX [POSIX 1003.2] - стандарта мобильных систем). Например, немалой популярностью пользуется язык cshell, есть также kshell, bashell (из наиболее популярных в последнее время) и другие. Более того, каждый пользователь может создать свой командный язык. Может одновременно на одном экземпляре операционной системы работать с разными командными языками.


    1. Основные понятия языка shell
    1.1. Ввод-вывод

    Три направления ввода-вывода являются выделенными - стандартный ввод, стандартный вывод и стандартный протокол. Как правило, команды берут исходные данные из стандартного ввода и помещают результаты в стандартный вывод.

    Стандартные ввод, вывод и протокол можно переназначить. Обозначение

    Code:
    < <имя файла>
    служит для переназначения стандартного ввода (дескриптор файла 0),

    Code:
     > <имя файла>
    для стандартного вывода (дескриптор файла 1);

    Code:
    << <строка>
    ввод происходит со стандартного ввода, пока не встретится указанная <строка> или конец файла,

    Code:
    >> <имя файла>
    для стандартного вывода; если файл существует, то выводимая информация добавляется к конец этого файла,

    Code:
    <& <цифра>
    в качестве стандартного ввода об(r)является файл, ассоциированный с дескриптором <цифра>; аналогично для стандартного вывода

    Code:
    >& <цифра>
            <&- и >&-
    закрывают соответственно стандартный ввод и вывод.

    Если любой из этих конструкций предшествует цифра, то с указанным файлом будет ассоциирован дескриптор, равный указанной цифре, вместо 0 и 1 по умолчанию. Например,

    Code:
    2 > <имя файла>
    для стандартного протокола используется дескриптор 2, а

    Code:
     2 >& 1
    ассоциирует дескриптор 2 с файлом, ассоциированным с дескриптором 1.

    Code:
     ...  2>protocol
    переназначает стандартный протокол (дескриптор 2) в файл по имени protocol.

    Чтобы переназначить стандартный протокол туда же, куда уже назначен стандартный вывод, следует употребить конструкцию

    Code:
    ...  2>&1
    Важен порядок переназначения: shell производит переназначение слева направо по указанному списку. Так,

    Code:
    1 > xxx 2 >& 1
    сначала ассоциирует дескриптор 1 с файлом xxx, а затем дескриптор 2 с 1, т.е. тоже с xxx. А

    Code:
     2 >& 1 1 > xxx
    ассоциирует дескриптор 2 с терминалом, а 1 - с файлом xxx.

    Можно переназначить системный ввод на текущий файл:

    Code:
    isql - - <
    1.2. Синхронное и асинхронное выполнение команд

    Обычно shell ждет завершения выполнения команды. Однако имеется возможность запустить задачу в асинхронном режиме, т.е. без ожидания ее завершения. Для этого после команды (после всех ее аргументов и указаний о переназначении ввода-вывода) надо поставить знак &. При этом по умолчанию стандартный ввод команды назначается на пустой файл /dev/null.

    Пример: создать файл primer можно по команде

    Code:
    echo > primer
    Еще пример: запустить программу prog в асинхронном режиме, чтобы не надо было дожидаться его завершения, засечь время выполнения, результаты программы направить в файл prog.res, данные о времени выполнения - в файл prog.tim.

    Code:
    time prog > prog.res 2> prog.tim &
    1.3. Конвейер

    Конвейер - последовательность команд, разделенных знаком |. Если после конвейера стоит ; shell ждет его завершения. Если & - то не ждет. Роль ; может играть конец строки. Смысл конвейера в том, что стандартный вывод одной команды замыкается на стандартный ввод другой. Пример конвейера - подсчитать число об(r)ектных файлов в текущем каталоге.

    Code:
     ls *.o | wc -l
    1.4. Метасимволы, генерация имен файлов

    Метасимволы - символы, имеющие специальное значение для интерпретатора :

    Code:
    ? * ; & ( ) | ^ < > <пробел> <табуляция> <возврат_каретки>
    
    Однако каждый из этих символов может представлять самого себя, если перед ним стоит \. Все символы, заключенные между кавычками ' и ', представляют самих себя. Между двойными кавычками (") выполняются подстановки команд (см п. 2.2) и параметров (см. п. 2.3), а символы \, `," и $ могут экранироваться предшествующим символом \.

    После всех подстановок в каждом слове команды ищутся символы *,?, и [. Если находится хотя бы один из них, то это слово рассматривается как шаблон имен файлов и заменяется именами файлов, удовлетворяющих данному шаблону (в алфавитном порядке). Если ни одно имя файла не удовлетворяет шаблону, то он остается неизменным. Значения указанных символов:
    Code:
    * 	любая строка, включая и пустую 	
    ? 	один любой символ 	
    [...] 	любой из указанных между ними символов.
    Пара символов, разделенных знаком -, означает любой символ, который находится между ними, включая и их самих. Если первым символом после "[" идет "!", то указанные символы не должны входить в имя файла.



    2. Синтаксис языка shell
    2.1. Комментарии

    Строки, начинающиеся с #, трактуются как комментарии.
    2.2. Подстановка результатов выполнения команд

    Выражения можно заключать в обратные кавычки (`). Такие выражения вычисляются в месте использования. Они могут быть, например, частью строк. Пример. Пусть параметром макрокоманды является имя файла с расширением .for. Требуется удалить одноименный файл с расширением .err.

    Code:
    name=`ena -n $1`
            rm -f ${name}.err
    Значение, полученное в результате выполнения команды

    Code:
    ena -n $1
    присваивается переменной name. Фигурные скобки использованы для выделения аргумента операции перехода от имени к значению. Без них .err приклеилась бы к имени.
    2.3. Переменные и подстановка их значений

    Все переменные в языке shell - текстовые. Их имена должны начинаться с буквы и состоять из латинских букв, цифр и знака подчеркивания (_). Чтобы воспользоваться значением переменной, надо перед ней поставить символ $. Использование значения переменной называется подстановкой.

    Различается два класса переменных: позиционные и с именем. Позиционные переменные - это аргументы командных файлов, их именами служат цифры: $0 - имя команды, $1 - первый аргумент и т.д. Значения позиционным переменным могут быть присвоены и командой set (см. Специальные команды). Пример. После вызова программы на shellе, хранящейся в файле ficofl:

    Code:
     ficofl -d / \*.for
    значением $0 будет ficofl, $1 - -d, $2 - /, $3 - *.for, значения остальных позиционных переменных будут пустыми строками. Заметим, что если бы символ * при вызове ficofl не был экранирован, в качестве аргументов передались бы имена всех фортранных файлов текущей директории.

    Еще две переменные хранят командную строку за исключением имени команды: $@ эквивалентно $1 $2 ..., а $* - "$1 $2 ...". Начальные значения переменным с именем могут быть установлены следующим образом:

    Code:
     <имя>=<значение> [ <имя>=<значение> ] ...
    Не может быть одновременно функции (см. Управляющие конструкции) и переменной с одинаковыми именами. Для подстановки значений переменных возможны также следующие конструкции:

    Code:
      ${<переменная>}
    если значение <переменной> определено, то оно подставляется. Скобки применяются лишь если за <переменной> следует символ, который без скобок приклеится к имени.

    Code:
    ${<переменная>:-<слово>}
    если <переменная> определена и не является пустой строкой, то подставляется ее значение; иначе подставляется <слово>.

    Code:
    ${<переменная>:=<слово>}
    если <переменная> не определена или является пустой строкой, ей присваивается значение <слово>; после этого подставляется ее значение.

    Code:
    ${<переменная>:?<слово>}
    если <переменная> определена и не является пустой строкой, то подставляется ее значение; иначе на стандартный вывод выводится <слово> и выполнение shellа завершается. Если <слово> опущено, то выдается сообщение "parameter null or not set".

    Code:
    ${<переменная>:+<слово>}
    если <переменная> определена и не является пустой строкой, то подставляется <слово>; иначе подставляется пустая строка.

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

    Code:
    echo ${d:-`pwd`}
    Следующие переменные автоматически устанавливаются shell'ом:
    Code:
    # 	количество позиционных параметров (десятичное) 	
    - 	флаги, указанные при запуске shellа или командой set 	
    ? 	десятичное значение, возвращенное предыдущей синхронно выполненной командой 	
    $ 	номер текущего процесса 	
    ! 	номер последнего асинхронного процесса 	
    @ 	эквивалентно $1 $2 $3 ... 	
    * 	эквивалентно "$1 $2 $3 ..." 	
    Напомним: чтобы получить значения этих переменных, перед ними нужно поставить знак $. Пример: выдать номер текущего процесса:

    Code:
    echo $$
    2.4. Специальные переменные

    Shell'ом используются следующие специальные переменные:
    Code:
    HOME 	директория, в которую пользователь попадает при входе в систему или при выполнении команды cd без аргументов 	
    PATH 	список полных имен каталогов, в которых ищется файл при указании его неполного имени. 	
    PS1 	основная строка приглашения (по умолчанию $) 	
    PS2 	дополнительная строка приглашения (по умолчанию >); в интерактивном режиме перед вводом команды shell'ом выводится основная строка приглашения.
    Если нажата клавиша new_line, но для завершения команды требуется дальнейший ввод, то выводится дополнительная строка приглашения 	
    IFS 	последовательность символов, являющихся разделителями в командной строке (по умолчанию это <пробел>, <табу[/SIZE]ляция> и <возврат_каретки>)

    3. Управляющие конструкции

    Простая команда - это последовательность слов, разделенная пробелами. Первое слово является именем команды, которая будет выполняться, а остальные будут переданы ей как аргументы. Имя команды передается ей как аргумент номер 0 (т.е. имя команды является значением $0). Значение, возвращаемое простой командой - это ее статус завершения, если она завершилась нормально, или (восьмеричное) 200+статус, если она завершилась аварийно.

    Список - это последовательность одного или нескольких конвейеров, разделенных символами ;, &, && или || и быть может заканчивающаяся символом ; или &. Из четырех указанных операций ; и & имеют равные приоритеты, меньшие, чем у && и ||. Приоритеты последних также равны между собой. Символ ; означает, что конвейеры будут выполняться последовательно, а & - параллельно. Операция && (||) означает, что список, следующий за ней будет выполняться лишь в том случае, если код завершения предыдущего конвейера нулевой (ненулевой).

    Команда - это либо простая команда, либо одна из управляющих конструкций. Кодом завершения команды является код завершения ее последней простой команды.
    3.1. Цикл ДЛЯ

    Code:
     for <переменная> [ in <набор> ]
            do
            <список>
            done
    Если часть in <набор> опущена, то это означает in "$@" ( то есть in $1 $2 ... $n). Пример. Вывести на экран все фортранные файлы текущей библиотеки:

    Code:
     for f in *.for
            do
            cat $f
            done
    3.2. Оператор выбора

    Code:
    case $<переменная> in
                    <шаблон> | <шаблон>... ) <список> ;;
                    . . .
            esac
    Оператор выбора выполняет <список>, соответствующий первому <шаблону>, которому удовлетворяет <переменная>. Форма шаблона та же, что и используемая для генерации имен файлов. Часть | шаблон... может отсутствовать.

    Пример. Определить флаги и откомпилировать все указанные файлы.

    Code:
    #       инициализировать флаг
    flag=
    #       повторять для каждого аргумента
    for a
    do
            case $a in
                    # об(r)единить флаги, разделив их пробелами
                    -[ocSO]) flag=$flag' ' $a ;;
                         -*) echo 'unknown flag $a' ;;
                    # компилировать каждый исходный файл и сбросить флаги
                        *.c) cc $flag $a; flag= ;;
                        *.s) as $flag $a; flag= ;;
                        *.f) f77 $flag $a; flag= ;;
                    # неверный аргумент
                          *) echo 'unexpected argument $a' ;;
            esac
    done
    3.3. Условный оператор.

    Code:
     if <список1>
            then
            <список2>
          [ elif <список3>
            then
            <список4> ]
            . . .
          [ else
            <список5> ]
            fi
    Выполняется <список1> и, если код его завершения 0, то выполняется <список2>, иначе - <список3> и, если и его код завершения 0, то выполняется <список4>. Если же это не так, то выполняется <список5>. Части elif и else могут отсутствовать.
    3.4. Цикл ПОКА

    Code:
     while <список1>
            do
            <список2>
            done
    До тех пор, пока код завершения последней команды <списка1> есть 0, выполняются команды <списка2>. При замене служебного слова while на until условие выхода из цикла меняется на противоположное.

    В качестве одной из команд <списка1> может быть команда true (false). По этой команде не выполняется никаких действий, а код завершения устанавливается 0 (-1). Эти команды применяются для организации бесконечных циклов. Выход из такого цикла можно осуществить лишь по команде break (см. Специальные команды).
    3.5. Функции

    <имя> () {
    <список>;
    }


    Определяется функция с именем <имя>. Тело функции - <список>, заключенный между { и }.
    3.6. Зарезервированные слова

    Следующие слова являются зарезервированными:

    Code:
     if      then    else    elif    fi
       case    in      esac    { }
       for     while   until   do      done
    3.7. Специальные команды

    Как правило, для выполнения каждой команды shell порождает отдельный процесс. Специальные команды отличаются тем, что они встроены в shell и выполняются в рамках текущего процесса.
    Code:
    [B]:[/B] 	Пустая команда. Возвращает нулевой код завершения. 	
    [B]. file[/B] 	Shell читает и выполняет команды из файла file, затем завершается; при поиске file используется список поиска $PATH. 	
    [B]break [n] [/B]	Выход из внутреннего for или while цикла; если указано n, то выход из n внутренних циклов. 	
    [B]continue [n] [/B]	Перейти к следующей итерации внутреннего for или while цикла; если указано n, то переход к следующей итерации n-ого цикла. 	
    [B]cd [ <аргумент> ][/B] 	Сменить текущую директорию на директорию <аргумент>. По умолчанию используется значение HOME. 	
    [B]echo [ <арг> ... ][/B] 	Выводит свои аргументы в стандартный вывод, разделяя их пробелами. 	
    [B]eval [ <арг> ... ][/B] 	Аргументы читаются, как если бы они поступали из стандартного ввода и рассматриваются как команды, которые тут же и выполняются. 	
    [B]exec [ <арг> ... ][/B] 	Аргументы рассматриваются как команды shell'а и тут же выполняются, но при этом не создается нового процесса. В качестве аргументов могут быть указаны направления ввода-вывода и, если нет никаких других аргументов, то будет изменено лишь направление ввода-вывода текущей программы. 	
    [B]exit [ n ][/B] 	Завершение выполнения shell'а с кодом завершения n. Если n опущено, то кодом завершения будет код завершения последней выполненной команды (конец файла также приводит к завершению выполнения). 	
    [B]export [ <переменная> ... ] [/B]	Данные переменные отмечаются для автоматического экспорта в окружение (см. Окружение) выполняемых команд. Если аргументы не указаны, то выводится список всех экспортируемых переменных. Имена функций не могут экспортироваться. 	
    [B]hash [ -r ] [ <команда> ... ][/B] 	Для каждой из указанных команд определяется и запоминается путь поиска. Опция -r удаляет все запомненные данные. Если не указан ни один аргумент, то выводится информация о запомненных командах: hits - количество обращений shell'а к данной команде; cost - объем работы для обнаружения команды в списке поиска; command - полное имя команды. В некоторых ситуациях происходит перевычисление запомненных данных, что отмечается значком * в поле hits. 	
    pwd 	Выводит имя текущей директории. 	
    [B]read [ <переменная> ... ] [/B]	Читается из стандартного ввода одна строка; первое ее слово присваивается первой переменной, второе - второй и т.д., причем все оставшиеся слова присваиваются последней переменной. 	
    [B]readonly [ <переменная> ... ][/B] 	Запрещается изменение значений указанных переменных. Если аргумент не указан , то выводится информация обо всех переменных типа readonly. 	
    [B]return [ n ][/B] 	Выход из функции с кодом завершения n. Если n опущено, то кодом завершения будет код завершения последней выполненной команды. 	
    [B]set [ --aefkntuvx [ <арг> ... ] ][/B] 	Команда устанавливает следующие режимы: 	
    -a 	отметить переменные, которые были изменены или созданы, как переменные окружения (см. Окружение) 	
    -e 	если код завершения команды ненулевой, то немедленно завершить выполнение shell'а 	
    -f 	запретить генерацию имен файлов 	
    -k 	все переменные с именем помещаются в окружение команды, а не только те, что предшествуют имени команды (см. Окружение) 	
    -n 	читать команды, но не выполнять их 	
    -t 	завершение shell'а после ввода и выполнения одной команды 	
    -u 	при подстановке рассматривать неустановленные переменные как ошибки 	
    -v 	вывести вводимые строки сразу после их ввода 	
    -x 	вывести команды и их аргументы перед их выполнением 	
    -- 	не изменяет флаги, полезен для присваивания позиционным переменным новых значений. 	
     	При указании + вместо - каждый из флагов устанавливает противоположный режим. Набор текущих флагов есть значение переменной $-. <арг> - это значения, которые будут присвоены позиционным переменным $1, $2 и т.д. Если все аргументы опущены, выводятся значения всех переменных. 	
    [B]shift [ n ][/B] 	Позиционные переменные, начиная с $(n+1), переименовываются в $1 и т.д. По умолчанию n=1. 	
    test 	вычисляет условные выражения (см. Дополнительные сведения. Test ) 	
    trap [ <арг> ] [ n ] ... 	Команда <арг> будет выполнена, когда shell получит сигнал n (см. Сигналы). (Надо заметить, что <арг> проверяется при установке прерывания и при получении сигнала). Команды выполняются по порядку номеров сигналов. Любая попытка установить сигнал, игнорируемый данным процессом, не обрабатывается. Попытка прерывания по сигналу 11 (segmentation violation) приводит к ошибке. Если <арг> опущен, то все прерывания устанавливаются в их начальные значения. Если <арг> есть пустая строка, то этот сигнал игнорируется shell'ом и вызываемыми им программами. Если n=0, то <арг> выполняется при выходе из shell'а. Trap без аргументов выводит список команд, связанных с каждым сигналом. 	
    ...
    [/SIZE]
    [SIZE=1][I]При написании статьи были использованы материалы с сайтов: http://www.citforum.ru ,  http://www.linuxcenter.ru/[/I][/SIZE]
     
    #1 mR_LiNK[deface_0nl, 7 Jan 2007
    Last edited: 7 Jan 2007
    2 people like this.
  2. guest3297

    guest3297 Banned

    Joined:
    27 Jun 2006
    Messages:
    1,246
    Likes Received:
    639
    Reputations:
    817
    У меня книжка Администратирование Linux даже разделы совпадают...
     
  3. mR_LiNK[deface_0nl

    mR_LiNK[deface_0nl Elder - Старейшина

    Joined:
    12 Dec 2006
    Messages:
    147
    Likes Received:
    27
    Reputations:
    13
    ...продолжение..

    type [ <имя> ... ] Для каждого имени показывает, как оно будет интерпретироваться при использовании в качестве имени команды: как внутренняя команда shell'а, как имя файла или же такого файла нет вообще.
    ulimit [ -f ] [ n ] Устанавливает размер файла в n блоков; -f - устанавливает размер файла, который может быть записан процессом-потомком (читать можно любые файлы). Без аргументов - выводит текущий размер.
    umask [ nnn ] Пользовательская маска создания файлов изменяется на nnn. Если nnn опущено, то выводится текущее значение маски. Пример: после команды umask 755 будут создаваться файлы, которые владелец сможет читать, писать и выполнять, а все остальные - только читать и выполнять.
    unset [ <имя> ... ] Для каждого имени удаляет соответствующую переменную или функцию. Переменные PATH, PS1, PS2 и IFS не могут быть удалены.
    wait [ n ] Ждет завершения указанного процесса и выводит код его завершения. Если n не указано, то ожидается завершения всех активных процессов-потомков и возвращается код завершения 0.



    4. Выполнение shell-программ

    4.1. Запуск shell'а

    Программа, интерпретирующая shell-программы, находится в файле /bin/sh. При запуске ее первый аргумент является именем shell-программы, остальные передаются как позициональные параметры. Если файл, содержащий shell-программу, имеет право выполнения (x), то достаточно указания лишь его имени. Например, следующие две команды операционной системы эквивалентны (если файл ficofl обладает указанным правом и на самом деле содержит shell-программу):

    Code:
     sh ficofl -d . g\*
    и
            ficofl -d . g\*
    4.2. Выполнение

    При выполнении shell-программ выполняются все подстановки. Если имя команды совпадает с именем специальной команды, то она выполнается в рамках текущего процесса. Так же выполняются и определенные пользователем функции. Если имя команды не совпадает ни с именем специальной команды, ни с именем функции, то порождается новый процесс и осуществляется попытка выполнить указанную команду.

    Переменная PATH определяет путь поиска директории, содержащей данную команду. По умолчанию это

    Code:
     ::/bin:/usr/ bin:/util:/dss/rk
    Директории поиска разделяются двоеточиями; :: означает текущую директорию. Если имя команды содержит символ /, значение $PATH не используется: имена, начинающиеся с / ищутся от корня, остальные - от текущей директории. Положение найденной команды запоминается shellом и может быть опрошено командой hash.
    4.3. Окружение

    Окружение - это набор пар имя-значение, которые передаются выполняемой программе. Shell взаимодействует с окружением несколькими способами. При запуске shell создает переменную для каждой указанной пары, придавая ей соответствующее значение. Если вы измените значение какой-либо из этих переменных или создадите новую переменную, то это не окажет никакого влияния на окружение, если не будет использована команда export для связи переменной shell'а с окружением (см. также set -a). Переменная может быть удалена из окружения командой unset (см.). Таким образом, окружение каждой из выполняемых shell'ом команд формируется из всех неизмененных пар имя-значение, первоначально полученных shell'ом, минус пары, удаленные командой unset, плюс все модифицированные и измененные пары, которые для этого должны быть указаны в команде export.

    Окружение простых команд может быть сформировано указанием перед ней одного или нескольких присваиваний переменным. Так,

    Code:
      TERM=d460 <команда>
    и
    Code:
     (export TERM; TERM=d460; <команда>)
    эквивалентны. Переменные, участвующие в таких присваиваниях, назовем ключевыми параметрами.

    Если установлен флаг -k (см. set), то все ключевые параметры помещаются в окружение команды, даже если они записаны после команды.
    4.4. Сигналы

    UNIX'ом поддерживаются следующие сигналы:
    Code:
    SIGHUP 	- 1 - 	отменить (hangup) 	
    SIGINT 	- 2 - 	прерывание (interrupt) 	
    SIGQUIT 	- 3 - 	нестандартный выход (quit) 	
    SIGILL 	- 4 - 	неверная команда (illegal instruction) 	
    SIGTRAP 	- 5 - 	ловушка (trace trap) 	
    SIGFPE 	- 8 - 	исключительная ситуация при выполнении операций с плавающей запятой (floating-point exception) 	
    SIGKILL 	- 9 - 	уничтожение процесса (kill) 	
    SIGBUS 	- 10 - 	ошибка шины (bus error) 	
    SIGSEGV 	- 11 - 	нарушение сегментации (segmentation violation) 	
    SIGSYS 	- 12 - 	неверный системный вызов (bad argument to system call) 	
    SIGPIPE 	- 13 - 	запись в канал без чтения из него (write on a pipe with no one to read it) 	
    SIGALRM 	- 14 - 	будильник (alarm clock) 	
    SIGTERM 	- 15 - 	программное завершение процесса (software termination signal) 
    Сигналы SIGINT и SIGQUIT игнорируются, если команда была запущена асинхронно. Иначе сигналы обрабатываются так же, как в процессе-предке, за исключением сигнала SIGSEGV (см. также Специальные команды. Trap).
    4.5. Замечания

    При выполнении команд запоминается их местонахождение. Поэтому при создании команды с тем же именем, но находящейся в другой директории, все равно будет выполняться старая команда (если вызов происходит по короткому имени). Для исправления ситуации воспользуйтесь командой hash с ключом -r (см. Специальные команды).

    Если вы переименовали текущую или вышележащую директорию, то команда pwd может давать неверную информацию. Для исправления ситуации воспользуйтесь командой cd с полным именем директории.


    5. Дополнительные сведения
    5.1. Команда test

    Команда test применяется для проверки условия. Формат вызова:

    Code:
    test <выражение>
            или
            [ <выражение> ]
    Команда test вычисляет <выражение> и, если его значение - истина, возвращает код завершения 0 (true); иначе - ненулевое значение (false). Ненулевой код завершения возвращается и если опущены аргументы. <Выражение> может состоять из следующих примитивов:
    Code:
    [B]-r файл[/B] 	- истина, если файл существует и доступен для чтения 	
    [B]-w файл[/B] 	- истина, если файл существует и доступен для записи 	
    [B]-x файл[/B] 	- истина, если файл существует и является выполняемым 	
    [B]-f файл[/B] 	- истина, если файл существует и является обычным файлом 	
    [B]-d файл[/B] 	- истина, если файл существует и является директорией 	
    [B]-c файл[/B] 	- истина, если файл существует и является специальным символьно-ориентированным файлом 	
    [B]-b файл[/B] 	- истина, если файл существует и является специальным блок-ориентированным файлом 	
    [B]-p файл[/B] 	- истина, если файл существует и является именованным каналом (pipe) 	
    [B]-s файл[/B] 	- истина, если файл существует и имеет ненулевую длину 	
    [B]-t [ дескриптор файла ][/B] 	- истина, если открытый файл с указанным дескриптором (по умолчанию 1) существует и ассоциирован с терминалом 	
    [B]-z s1[/B] 	- истина, если длина строки s1 нулевая 	
    [B]-n s1[/B] 	- истина, если длина строки s1 ненулевая 	
    [B]s1 = s2[/B] 	- истина, если строки s1 и s2 совпадают 	
    [B]s1 != s2[/B] 	- истина, если строки s1 и s2 не совпадают 	
    [B]s1[/B] 	- истина, если s1 непустая строка 	
    [B]n1 -eq n2[/B] 	- истина, если целые n1 и n2 алгебраически совпадают . На месте -eq могут быть также -ne, -gt, -ge, -lt, -le 	
    5.2. Команда expr

    Команда expr применяется для вычисления выражений. Результат выводится на стандартный вывод. Операнды выражения должны быть разделены пробелами. Метасимволы должны быть экранированы. Надо заметить, что 0 возвращается в качестве числа, а не для индикации пустой строки. Строки, содержащие пробелы или другие специальные символы, должны быть заключены в кавычки. Целые рассматриваются как 32-битные числа.

    Ниже приведен список операторов в порядке возрастания приоритета, операции с равным приоритетом заключены в фигурные скобки. Перед символами, которые должны быть экранированы, стоит \.
    Code:
    [B]<выр> \| <выр>[/B]	если первое <выр> не пустое и не нулевое, то возвращает его, иначе возвращает второе <выр> 	
    [B]<выр> \& <выр>[/B]	если оба <выр> не пустые и не нулевые, то возвращает первое <выр>, иначе возвращает 0 	
    [B]<выр> { =, \>, \>=, \<, \<=, != } <выр>[/B]	возвращает результат целочисленного сравнения если оба <выр> - целые; иначе возвращает результат лексического сравнения 	
    [B]<выр> { +, - } <выр>[/B]	сложение и вычитание целочисленных аргументов 	
    [B]<выр> { \*, /, % } <выр>[/B]	умножение, деление и получение остатка от деления целочисленных аргументов 	
    [B]<выр> : <выр>[/B]	оператор сопоставления : сопоставляет первый аргумент со вторым, который должен быть регулярным выражением. Обычно оператор сравнения возвращает число символов, удовлетворяющих образцу (0 при неудачном сравнении). Однако символы \( и \) могут применяться для выделения части первого аргумента. 
    Регулярное выражение строится следующим образом:
    Code:
    . 	- обозначает любой символ 	
    * 	- обозначает предыдущий символ, повторенный несколько раз 	
    [] 	- обозначают любой один из указанных между ними символов; группа символов может обозначаться с помощью знака "-" (т.е. [0-9] эквивалентно [0123456789]); если после [ стоит ^, то это эквивалентно любому символу, кроме указанных в скобках и <возврата_каретки>; для указания ] в качестве образца, надо поставить ее сразу за [ (т.е. []...]); . и * внутри квадратных скобок обозначают самих себя
    Все остальные символы (и ^, если стоит не в квадратных скобках) обозначают самих себя. Для указания символов ., *,[ и ] надо экранировать их (т.е. писать \., \*, \[, \]).
    Примеры.

    Code:
    1.
    
       a=`expr $a + 1`
    
    - увеличение на 1 переменной a 
    2.

    Code:
      expr $a : '.*/\(.*\)' \| $a 
    - выделяет из имени файла короткое имя (т.е. из /usr/util/ena выделяется ena). Внимание, одиночный символ / будет воспринят как знак операции деления.

    3.

    Code:
    expr $VAR : '.*' 
    - получение количества символов переменной VAR.

    В качестве побочного эффекта expr возвращает следующие коды завершения:
    0 - если выражение не нуль и не пустая строка
    1 - если выражение нуль или пустая строка
    2 - для некорректных выражений

    Команда expr также выдает следующие сообщения об ошибках:
    Code:
    [B]syntax error[/B] 	- для ошибок в операторах или операндах 	
    [B]non-numeric argument[/B] 	- для попыток применения арифметических операций к нечисловым строкам 	
    Замечание.
    Допустим, что мы хотим сравнить значение переменной a с каким-либо символом, имеющим для expr особый смысл, например, со знаком равенства. Пусть $a на самом деле является знаком равенства. Так как аргументы предварительно обрабатываются shell'ом, то команда

    Code:
    expr $a = '='
    будет воспринята как

    Code:
    expr = = =
    что синтаксически некорректно. В подобных случаях надо пользоваться таким приемом:

    Code:
    expr X$a = X=
    т.е. добавлением некоторого символа к обеим строкам, что никак не влияет на результат сравнения, однако позволяет избежать синтаксической ошибки.
    5.3. Команда ena

    Команда ena позволяет получить части полного имени файла. Первый аргумент - флаг, второй - имя файла. Команда различает следующие флаги:
    Code:
    [B]-n [/B]	- имя файла без расширения 	
    [B]-f[/B] 	- имя файла с расширением 	
    [B]-e[/B] 	- расширение 	
    [B]-d[/B] 	- имя директории 	
    [B]-p[/B] 	- если имя файла начинается с . или .. , то эти символы выделяются из имени
    Ниже приводится текст программы ena, хранящийся в /util/ena.

    Code:
    #       Get part of pathname
       case    $1      in
       -n )
              expr $2 : '.*/\(.*\)[.].*' \| $2 : '\(.*\)[.].*' \| $2
              ;;
       -f )
              expr $2 : '.*/\(.*\)' \| $2
              ;;
       -e )
              expr $2 : '.*\([.][^./]*\)' \| ' '
              ;;
       -d )
              expr $2 : '\(.*\)/.*' \| $2
              ;;
       -p )
              expr $2 : '\([.]\)/.*' \| $2 : '\([.][.]\)/.*' \| ' '
              ;;
       *  )
              echo "error: unknown part of pathname $1"
              exit 2
              ;;
       esac


    На этом я заканчиваю длинное повествование о столь мощном языке мобильного программирования.
    Как дополнительный материал хочу выделить электронныу книгу о программирование в стандарте POSIX (http://www.intuit.ru/department/se/pposix/2/)

    {============================================================}
    По поводу замечаний сказаных ниже::
    Весь материал был взят с указанных сайтов, скомпанован, немного отредактирован и представлен в позновательных целях. Соответственно я не претендую на полное авторство данной статьи..
    з.ы.В дальнейшем статья будет редактироваться и дополняться новым и авторским (то бишь от меня) материалом.

    При написании статьи были использованы материалы с сайтов: http://www.citforum.ru , http://www.linuxcenter.ru/
     
    #3 mR_LiNK[deface_0nl, 7 Jan 2007
    Last edited: 7 Jan 2007
  4. mR_LiNK[deface_0nl

    mR_LiNK[deface_0nl Elder - Старейшина

    Joined:
    12 Dec 2006
    Messages:
    147
    Likes Received:
    27
    Reputations:
    13
    Не спорю, вполне может быть, копирайты выставлены
     
    1 person likes this.
  5. Gh0s7

    Gh0s7 Elder - Старейшина

    Joined:
    23 Nov 2006
    Messages:
    160
    Likes Received:
    231
    Reputations:
    242
    Что-то мне не верится что это аффтар написал..
    Переместите в "чужие статьи"
     
  6. Gh0s7

    Gh0s7 Elder - Старейшина

    Joined:
    23 Nov 2006
    Messages:
    160
    Likes Received:
    231
    Reputations:
    242
    Как-то странно они выставлены. Как будто статью писал ты, юзая маны с тех сайтов, а на деле простой копипаст.
     
  7. netf0x

    netf0x Elder - Старейшина

    Joined:
    27 Apr 2006
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    А вот такой вопрос:
    есть файл вида:

    Interesting ports on 1.1.72.66:
    21/tcp filtered ftp
    Interesting ports on 1.1.72.67:
    21/tcp open ftp
    Interesting ports on 1.1.72.68:
    21/tcp filtered ftp
    Interesting ports on 1.1.72.69:
    21/tcp filtered ftp
    Interesting ports on 1.1.72.70:
    21/tcp open ftp
    Interesting ports on 1.1.72.71:
    21/tcp filtered ftp
    ...

    не силен в регулярных выражениях((
    как на bash отделить в отдельный файл вида ip:port open???
     
  8. -=lebed=-

    -=lebed=- хэшкрякер

    Joined:
    21 Jun 2006
    Messages:
    3,804
    Likes Received:
    1,960
    Reputations:
    594
    Да вот ИМХО один в один написано, даже нумерация пунктов совпадает... походу копипаст в чистом виде, никакой компоновки не заметил...

    p.s. Этот текст подготовлен НПО "КЛОТО"
    Last-modified: Sun, 07 Jul 2002 09:31:58 GMT
     
  9. GreenBear

    GreenBear наркоман с медалью

    Joined:
    7 May 2005
    Messages:
    2,547
    Likes Received:
    1,398
    Reputations:
    612
    да. перемещено.
     
  10. Gh0s7

    Gh0s7 Elder - Старейшина

    Joined:
    23 Nov 2006
    Messages:
    160
    Likes Received:
    231
    Reputations:
    242
    Я бы сделал это на перле.

    Code:
    #!/usr/bin/perl
    
    open (IN, "<$ARGV[0]") or die;
    while (<IN>) {
      chomp;
      if (/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/) { $was_ip = $&; next; }
      if (/[0-9]{1,5}\/tcp open/) {($port, $foo) = split (/\//, $&); print $port;print "$was_ip:$port\n"; }
    }
    close IN;
    exit 0;
    
     
  11. Constantine

    Constantine Elder - Старейшина

    Joined:
    24 Nov 2006
    Messages:
    798
    Likes Received:
    710
    Reputations:
    301
    А мне чето не понравилась статья, ничо не выделено, не подчеркнуто, через пару минут текст сливаеться в одно сплошное пятно , ИМХО не читаемо. Раз уж статья очевидно копипаст-то хотябы потрудился бы над оформлением =(
     
    #11 Constantine, 10 Jan 2007
    Last edited: 10 Jan 2007