admin / 18.11.2017

Bash сравнение строк

Отсутствуют пробелы.

означает

тебе нужно

или даже

которая работает даже при .

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

Котировки не нужны (на самом деле, с правой стороны они имеют особое значение – они предотвращают расширение). Вы можете использовать вместо , также.

Содержание

Пропущенная запятая

Код выглядит так:

use strict; use warnings; print 42 «\n»; my $name = «Foo»;

а сообщение об ошибке

String found where operator expected at ex.pl line 4, near «42 «\n»» (Missing operator before «\n»?) syntax error at ex.pl line 4, near «42 «\n»» Execution of ex.pl aborted due to compilation errors.

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

В данном случае проблема была в том, что мы забыли запятую (,) после числа 42. Эта строчка должна выглядеть так: print 42, «\n»;.

String found where operator expected

В этом коде мы пропустили оператор конкатенации .

Как сравнить 2 числа на bash?

и получили такое же сообщение об ошибке:

use strict; use warnings; my $name = «Foo» «Bar»; String found where operator expected at ex.pl line 4, near «»Foo» «Bar»» (Missing operator before «Bar»?) syntax error at ex.pl line 54, near «»Foo» «Bar»» Execution of ex.pl aborted due to compilation errors.

На самом деле код должен был выглядеть так: my $name = «Foo» . «Bar»;.

Number found where operator expected

Этот код

use strict; use warnings; my $x = 23; my $z = $x 19;

выдает такую ошибку:

Number found where operator expected at ex.pl line 5, near «$x 19» (Missing operator before 19?) syntax error at ex.pl line 5, near «$x 19» Execution of ex.pl aborted due to compilation errors.

Здесь, видимо, не хватает оператора сложения + или умножения *, ну или оператора повтора x.

Ошибка синтаксиса, когда не хватает запятой

Отсутствующая запятая не всегда понимается интерпретатором, как пропущенный оператор. Например, этот код:

use strict; use warnings; my %h = ( foo => 23 bar => 19 );

Генерирует такую ошибку: syntax error at … line …, near «bar», без дополнительных деталей.

Добавление запятой после числа 23 исправит код:

my %h = ( foo => 23, bar => 19 );

Я предпочитаю добавлять запятую после каждой пары в хэше (то есть, в данном случае, после 19):

my %h = ( foo => 23, bar => 19, );

Эта привычка в большинстве случаев помогает избежать таких ошибок.

Scalar found where operator expected at

use strict; use warnings; my $x = 23; my $y = 19; my $z = $x $y; Scalar found where operator expected at … line 7, near «$x $y» (Missing operator before $y?) syntax error at … line 7, near «$x $y» Execution of … aborted due to compilation errors.

Опять же, между $x и $y может быть числовой или строковый оператор.

Array found where operator expected

use strict; use warnings; my @x = (23); my $z = 3 @x;

С какими еще случаями вы часто сталкиваетесь?

Знаете ли вы другие интересные случаи, в которых мы получаем такую синтаксическую ошибку?

Это сообщение об ошибке встречается действительно часто. Однако понять его может быть довольно сложно.

Дело в том, что люди знают о числовых операторах и строковых операторах, но не рассматривают запятую (,) как оператор. Терминология сообщения об ошибке немного вводит их в заблуждение.

Давайте рассмотрим пару примеров:

Comments

Bash в примерах. Часть вторая.

Еще больше основ программирования в bash

Обработка аргументов

Давайте разберемся как передавать и обрабатывать аргументы скрипта и ознакомимся с основными управляющими конструкциями bash.

В простом скрипте из предыдущей статьи мы использовали переменную «$1«, которая содержит первый аргумент командной строки при вызове скрипта. Аналогично можно использовать «$2», «$3» и так далее для доступа ко второму, третьему… аргументам командной строки. Вот пример:

Обратите внимание, что в переменной «$0» содержится имя самого скрипта, который запущен из командной строки. А переменная «$#» содержит количество переданных скрипту аргументов. Использование фигурных скобок необязательно только для переменных состоящих из одной цифры (с $0 по $9). Попробуйте позапускать этот скрипт с разным числом аргументов и посмотрите как он работает.

Иногда необходимо сослаться сразу на все аргументы командной строки. Для этого в bash есть специальная переменная «$@«, которая содержит все аргументы переданные скрипту разделенные пробелами. Мы будем использовать эту переменную чуть позже при рассказе о циклах со счетчиком (конструкция «for»).

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

Если вы раньше программировали на процедурных языках, таких как Си, Паскаль, Перл и тому подобных, вам должны быть знакомы управляющие конструкции вроде «if», «for» и другие. В bash тоже есть все эти конструкции. В следующих разделах пособия я познакомлю вас с ними и покажу чем они отличаются от подобных конструкций из других языков программирования. Если вы раньше не программировали — не волнуйтесь. Материал будет изложен подробно и дополнен примерами, так что даже новичок в программировании сможет разобраться.

Оператор условного выбора «if»

Если вы раньше программировали на языке Си, то должны знать сколько требуется усилий чтобы определить какой из двух файлов был создан первым, например. А все из-за того, что в Си нет встроенных средств для такого рода сравнения. Вместо этого приходится использовать системный вызов stat() для каждого файла и затем сравнивать результат вручную. Но в bash есть встроенный механизм сравнения файлов, Поэтому узнать «доступен ли для чтения файл /tmp/myfile» настолько же просто как и узнать «превосходит ли значение переменной ‘myvar’ 4».

Привожу список наиболее часто употребляемых в bash операторов сравнения

Файлы

-a file
истинно если файл существует.
-d file
истинно если файл существует и является директорией.
-f file
истинно если файл существует и является обычным файлом.
-r file
истинно если файл существует и доступен для чтения.
-s file
истинно если файл существует и его размер больше 0.
-w file
истинно если файл существует и доступен для записи.
-x file
истинно если файл существует и является исполняемым.
file1 -nt file2
истинно если файл file1 новее чем file2 или file1 (в соответствии со временем последнего изменения) существует, а file2 нет.
file1 -ot file2
истинно если файл file1 старше чем file2 или file2 существует, а file1 нет.
file1 -ef file2
истинно если оба файла ссылаются на одно и то же устройство или инод.

Строки

-z string
истинно если строка имеет нулевую длину.
-n string
истинно если длина строки не нулевая.
string1 = string2
истинно если строки равны.
string1 != string2
истинно если не равны.
string1 < string2
истинно если строка 1 стоит в алфавитном порядке перед строкой 2.
string1 > string2
истинно если строка 1 стоит в алфавитном порядке после строки 2.

В следующих примерах показано как использовать оператор сравнения в конструкции «if»:

Квадратные скобки вычисляют условное выражение стоящее в них (это синоним встроенной функции bash — test). Возвращаемый результат — 1 или 0 в зависимости от того выполняется условие или нет. в скобках может стоять несколько выражений, связанных логическими операторами «и» или «или«. Подробнее на странице справки help test.

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

В первой конструкции из предыдущего примера использована операция арифметического сравнения, а во втором — операция сравнения строк.

Тонкости при сравнении строк

В большинстве случаев, когда вы не заключаете строки и строковые переменные в двойные кавычки, это может привести к ошибке. Почему? Да потому что в строке может встретится пробел или символ табуляции, которые bash не сможет правильно обработать. Вот пример некорректного сравнения строк:

В этом примере, если значение переменной «$myvar» будет равно «foo», код будет работать как и ожидается и не печатать ничего. Но если значение переменной «$myvar» будет равно «foo bar oni», скрипт вызовет следующую ошибку:

После подстановки значения переменной, bash пытается произвести следующую операцию сравнения:

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

Этот код будет работать корректно и не преподнесет нам больше никаких неприятных сюрпризов.

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

Конструкция создания циклов «for»

Хорошо, с условными переходами разобрались, пора перейти к циклическим конструкциям. Начнем с управляющей конструкции «for«. Вот стандартный пример:

Что же именно произошло? Часть «for x» цикла «for» определяет переменную (называемую итератором) «$x», которая последовательно принимает значения «one», «two», «three», и «four» (по одному за один такт цикла). После присвоения каждого нового значения переменной «$x», выполняется тело цикла (код между словами «do» и «done»). В теле цикла мы выводим на печать значение переменной «$x». Заметим, что после слова «in» в конструкции «for» всегда стоит некий список. В данном примере мы указали четыре слова, но этот список может содержать имена файлов или даже шаблон (wildcard). В следующем примере показано как использовать шаблоны при инициализации итератора цикла:

Код этого цикла исполнится для каждого файла из /etc/ имя которого начинается с «r». Сначала bash найдет все такие файлы и заменит шаблон строкой /etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rc3.d /etc/rc4.d … /etc/rsyslog.d перед тем как приступить к выполнению цикла. В теле цикла для каждого файла из списка проверяется является ли этот файл директорией при помощи оператора «-d«. Если файл оказался директорией, рядом с его называнием печатается «(dir)».

В списке инициализации итератора можно использовать несколько шаблонов одновременно и даже переменные окружения:

Bash в этом примере подставляет значение переменной и раскрывает шаблоны. А затем копирует все файлы в заданную директорию.

До этого все примеры содержали шаблоны основанные на абсолютных путях, но можно использовать и относительные:

В этом примере bash раскрывает шаблон относительно текущей рабочей директории (не той в которой находится скрипт, а той которую показывает команда «pwd»). Поиграйтесь с этим скриптом, позапускайте его из разных директорий и посмотрите на результат.

Иногда может потребоваться запустить цикл по списку аргументов из командной строки. Вот как это делается:

В этом примере мы использовали переменную «$@» о которой говорили выше.

Арифметика в shell

Перед тем как приступить к разбору следующего вида циклической конструкции, научимся при помощи интерпретатора производить простые арифметические операции. Просто заключите арифметическое выражение в конструкцию «$(( ))» и bash посчитает ее значение. Вот несколько примеров:

Теперь, когда вы познакомились с вычислением арифметических выражений в shell, пришло время рассказать о циклических конструкциях «while» и «until».

Циклические конструкции с условиями («while» и «until»)

«while»–цикл исполняется пока выражение в квадратных скобках истинно. Он имеет следующий формат:

В следующем примере тело цикла исполняется ровно 10 раз:

После каждого выполнения кода тела цикла переменная «myvar» увеличивается на 1. Когда значение переменной становится равным 10, условие в квадратных скобках не выполняется и цикл прерывается.

«Until»–цикл очень похож на «while»–цикл: он повторяется пока выражение в квадратных скобках ложно. Вот пример «until»–цикла по функциональности идентичного «while»–циклу из предыдущего примера:

Экстренный выход из цикла

Для экстренного выхода из «for», «while» или «until» цикла используется команда break. Для выхода из нескольких вложенных циклов — break N, где N — количество вложенных циклов.

В последнем примере: «while :» — бесконечный цикл.

Сравнение строк в bash

Двоеточие — это команда bash которая не делает ничего но всегда завершается успехом. Переменная $? содержит статус с которым завершилась последняя команда (подробнее о специальных переменных смотри man bash). В нашем случае код отличный от 0 обозначает что при скачивании файла произошла ошибка. Как только условие в квадратных скобках выполнено, интерпретатор переходит к исполнению команды стоящей после логического и (&&). Break прерывает выполнение цикла.

Предпоследнюю строку предыдущего примера можно заменить на знакомую нам условную конструкцию «if» (помним, что в bash одно действие можно сделать несколькими разными способами):

то же самое но через условную конструкцию:

Или в одну строку

Да, конструкции можно записывать в одну строку, только нужно поставить несколько разделяющих знаков «точка с запятой». Но не стоит привыкать к такой форме записи — это усложняет читаемость кода.

Команда–переключатель «case»

Конструкция условного перехода «case» может оказаться очень полезной. Вот пример ее использования:

В этом примере сначала происходит обработка строки в переменной «$x» — «${x##*.}». Как мы помним из первой статьи, после этой операции в переменной «$x» остается только расширение файла. Затем bash сравнивает это расширение с вариантами стоящими слева от одинарных скобок «)«. Если совпадение найдено, выполняется соответствующее действие. Если совпадения не найдено, никаких действий не выполняется, но в данном конкретном коде совпадение будет всегда, потому что в последней строке стоит шаблон «*«, совпадающий с любой последовательностью символов.

Функции и пространство имен

В bash вы можете определять свои функции, как и в других языках программирования (C, Pascal…). Эти функции могут принимать аргументы, используя механизм очень похожий на механизм работы с аргументами командной строки. Вот пример определения простой функции:

Эта функция может быть переписана с использованием конструкции «case«. Сможете ли вы проделать это самостоятельно?

Выше мы определили функцию с именем «tarview», которая принимает один аргумент — имя тарбола. Эта функция определяет вид тарбола (без сжатия, сжатый gzip-ом или bzip2) по расширению, затем печатает этот тип и показывает содержимое архива. Если формат определить не удалось, выводится соответствующее сообщение. Вот пример вызова функции:

Как вы видите, обращение к аргументам внутри функции происходит по тем же именам как и к аргументам командной строки внутри скрипта. Переменная «$#» содержит количество переданных функции аргументов. Единственное что остается по-прежнему — переменная «$0«. Она содержит название скрипта при вызове функции из скрипта или строку «bash» при вызове функции напрямую из командной строки.

Вызвать функцию из командной строки можно следующим образом: сохраняем код функции в файл (например с названием «myfunc.txt») а затем даем следующую команду:

или что тоже самое

Эти команды строка за строкой исполняют инструкции написанные в файле в текущей командной оболочке. (Можно так же напечатать код функции строка за строкой в командной строке, но первый способ намного удобнее). После этого можем вызывать нашу функцию прямо из командной строки:

Замечание: любая функция может быть записана в файл ~/.bashrc или ~/.bash_profile, тогда вы сможете вызывать ее из командной строки в любое время при следующем логине.

Пространство имен

Часто возникает потребность создать переменную окружения внутри функции. В большинстве компилируемых языков (например Си), когда вы создаете переменную внутри функции, она попадает в отдельное пространство имен этой функции. Например, если вы напишите функцию «my function» на C и внутри этой функции создадите переменную «x», то она никак не повлияет на переменную с тем же именем «x», созданную вне функции «myfunction».

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

Результатом исполнения этого кода будет строка «ne two three three«, показывающая что переменная «myvar», созданная внутри функции перезаписала значение глобальной переменной «myvar» и что последнее значение итератора «x» равное «three» продолжило существование даже после завершения функции.

В этом простом примере ошибку легко заметить и устранить, переименовав переменные внутри функции. Но есть гораздо более правильное решение этой проблемы: при создании переменной можно явно указать что она является локальной при помощи инструкции «local«. Созданная таким способом внутри функции переменная будет отнесена к локальному пространству имен этой функции и не сможет никак повлиять на глобальную переменную с таким же именем. Следующий пример демонстрирует возможность создания локальной переменной:

Результатом выполнения этого кода будет строка «hello» — значение глобальной переменной «myvar» (на которую никак не повлияла локальная переменная «myvar», созданная внутри функции), а локальная переменная «x» перестает существовать после завершения функции.

Единственное условие при котором вы не должны использовать локальные переменные внутри функций — если хотите изменить значение глобальной переменной.

Подведение итогов

Вот и все. Теперь вы имеете представление о программировании в bash и можете писать свои скрипты. За более подробной информацией обращайтесь к справке man bash или к руководству Advanced Bash-Scripting Guide

Смотри также


Оригинал статьи— Bash by example, Part 2 (eng)

Ошибка в синтаксисе команды netdomen

Я
   dirar

 

24.09.13 — 11:50

Подскажите пожалуйста, где ошибка в команде
netdomen join comp /Domain:test.net /UserD:Administrator /PasswordD:*

 
 

   zva

 

1 — 24.09.13 — 12:04

netdom всю жизнь был, да и ммя юзера лучше domen\user вводить

   dirar

 

2 — 24.09.13 — 13:35

все равно не проходит

   dirar

 

3 — 24.09.13 — 13:36

Делаю так
netdom join comp /Domain:test.net /UserD:test.net\Administrator /PasswordD:*

   zva

 

4 — 24.09.13 — 13:43

ОС какая?

   dirar

 

5 — 24.09.13 — 13:45

Windows XP

   zva

 

6 — 24.09.13 — 13:47

netdom join comp /Domain:test.net /UserD:Domain\Administrator /PasswordD:*
а так?

   dirar

 

7 — 24.09.13 — 13:50

нет, к сожалению

   dirar

 

8 — 24.09.13 — 13:50

все время пишет, что синтаксическая ошибка.

как это может быть?

   dirar

 

9 — 24.09.13 — 13:52

у вас проходит команда в таком виде?

   zva

 

10 — 24.09.13 — 13:53

имя компьютера латиницей без пробелов?

 
 

   zva

 

11 — 24.09.13 — 13:53

"Кроме графического интерфейса можно включить компьютер в домен с помощью командной строки. В состав операционной системы Windows XP включена утилита NETDOM, которая может добавить компьютер в домен с помощью команды:
netdom join computer_name /domain:domain_name /userd:domain_name\user_name /passwordd:user_pass.

Где computer_name, domain_name и user_name нужно соответственно заменить именами добавляемого компьютера, домена и пользователя, а user_pass поменять на пароль пользователя в домене. "

   dirar

 

12 — 24.09.13 — 13:56

да

   dirar

 

13 — 24.09.13 — 13:58

dns тоже указал. и шлюз указал заранее

   Йохохо

 

14 — 24.09.13 — 14:00

http://technet.microsoft.com/en-us/library/cc788049.aspx

   dirar

 

15 — 24.09.13 — 14:09

всем спасибо, получилось в таком виде
netdom join comp /d:test.net /ud:Domain\Administrator /pd:*

 

TurboConf 5 — расширение возможностей Конфигуратора 1С

ВНИМАНИЕ!

Bash сравнение строк

Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку «Обновить» в браузере.

Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.

Вернуться к оглавлению

Операторы сравнения в Bash


Раньше при написании скриптов путался: где квадратные скобки, где круглые, где пробелы… Потом решил всё это дело изучить и классифицировать. И по мотивам статей с англоязычных сайтов получилось вот что:

Оператор Назначение К о н с т р у к ц и и
test [ … ] [[ … ]] (( … ))
-eq равно * * *
-ne неравно * * *
-gt больше * * *
-lt меньше * * *
-ge больше или равно * * *
-le меньше или равно * * *
= равно * * *
== равно (ASCII) * * * *
!= неравно * * * *
> больше (ASCII) * *
< меньше (ASCII) * *
>= больше или равно *
<= меньше или равно *
\> больше (ASCII) * *
\< меньше (ASCII) * *

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

Конструкция

[shonty@~]$ test 27 -gt 5; echo $? 0[shonty@~]$ test {27} \> 5; echo $? 0 При использование с операторами , , числа более 10 необходимо заключать в фигурные скобки, иначе результат будет неверный: [shonty@~]$ test 27 \> 5; echo $? 1 Также неверный результат будет, если не ставить обратный слэш «» перед знаками неравенства. [shonty@~]$ test {27} > 5; echo $?

Bash в примерах. Часть вторая.

1

Конструкция

NOTE При составлении выражений необходимо проставлять пробелы. [shonty@~]$ [ 27 -gt 5 ]; echo $? 0[shonty@~]$ [ {27} \> 5 ]; echo $? 0 При использование с операторами , , числа более 10 необходимо заключать в фигурные скобки, иначе результат будет неверный (с переменными и символами ASCII работает стабильно.): [shonty@~]$ [ 27 \> 5 ]; echo $? 1

Конструкция

NOTE При составлении выражений необходимо проставлять пробелы. [shonty@~]$ [[ 27 -gt 5 ]]; echo $? 0 При использовании операторов и , при числовых значениях более 10 возможны ошибки. Заключение чисел в фигурные скобки ситуацию не исправляет (с переменными и символами ASCII работает стабильно). [shonty@~]$ [[ 27 > 5 ]]; echo $? 1

Конструкция

При составлении выражений пробелы необязательны. С символами ASCII не работает [shonty@~]$ ((27>5)); echo $? 0

Теги: Linux, Bash, Операторы сравнения, -eg, -ne, -gt, -lt, -ge, -le, test, [ … ], [[ … ]], синтаксис, значение, оператор, символы, ASCI,

Вернуться к оглавлению

В

команда выполняет системный вызов (не ) по пути, хранящемуся в и возвращает true, если этот системный вызов завершается успешно, а тип файла, возвращаемый является «регулярным».

Поэтому, если возвращает true, вы можете сказать, что файл существует и является обычным файлом или символической ссылкой, в конечном итоге разрешающей обычный файл (или, по крайней мере, это было во время ).

Однако, если он возвращает false (или если или возвращает true), существует много разных возможностей:

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

Короче говоря, это должно быть:

Чтобы точно знать, что файл не существует, нам понадобится системный вызов для возврата с кодом ошибки ( сообщает, что один из компонентов пути не является каталогом, это другой случай, когда мы можем сказать файл не существует по этому пути). К сожалению команда не сообщает нам об этом. Он вернет false, является ли код ошибки ENOENT, EACCESS (разрешение отклонено), ENAMETOOLONG или что-то еще.

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

По крайней мере, говорит мне, что это не потому, что файл не существует, что он терпит неудачу. Это потому, что он не может определить, существует ли файл или нет.

Сравнение строк в Bash

Эта команда просто проигнорировала проблему.

С оболочкой вы можете запросить код ошибки с помощью специальной переменной после команды failing command и декодировать этот номер, используя специальный массив в модуле :

(остерегайтесь, что поддержка нарушена некоторыми версиями при построении с последними версиями ).

FILED UNDER : IT

Submit a Comment

Must be required * marked fields.

:*
:*