LINUX.ORG.RU

Bash команда test отказывается работать по ману

 ,


0

1

имеется:

--> cat upup.sh 
if [ ( pgrep chromium 1>/dev/null ) ] 
then
echo 'open'
else
echo 'close'
fi
выдает ошибку
--> ./upup.sh  
./upup.sh: строка 1: синтаксическая ошибка рядом с неожиданным маркером «pgrep»
./upup.sh: строка 1: `if [ ( pgrep chromium 1>/dev/null ) ] '

в мане сказано:

SYNOPSIS

test EXPRESSION 
test

[ EXPRESSION ] 
[ ] 
[ OPTION  

DESCRIPTION

Exit with the status determined by EXPRESSION.

--help
display this help and exit
--version
output version information and exit
An omitted EXPRESSION defaults to false. Otherwise, EXPRESSION is true or false and sets exit status. It is one of:

( EXPRESSION )
EXPRESSION is true

мануал или баш сутулится???

★★
Ответ на: комментарий от futurama

так не работает, пишет чо:

--> ./upup.sh 
./upup.sh: строка 2: pgrep chromium 1>/dev/null: Нет такого файла или каталога

safocl ★★
() автор топика
Ответ на: комментарий от safocl

короче работает только так:

`--> cat upup.sh 
#! /bin/bash
if [ "pgrep chromium 1>/dev/null" ]
then
        echo 'yes'
else
        echo 'no'
fi

а еще вот так:

`--> cat upup.sh 
#! /bin/bash
if `pgrep chromium 1>/dev/null`
then
        echo 'yes'
else
        echo 'no'
fi

а еще вот так:

`--> cat upup.sh 
#! /bin/bash
if $(pgrep chromium 1>/dev/null)
then
        echo 'yes'
else
        echo 'no'
fi

а вот так не работает:

`--> cat upup.sh 
#! /bin/bash
if "pgrep chromium 1>/dev/null"
then
        echo 'yes'
else
        echo 'no'
fi

safocl ★★
() автор топика
Последнее исправление: safocl (всего исправлений: 1)
Ответ на: комментарий от aedeph_

ну а чо запускать то? выведет ошибку, и то чо там код возврата 2 будет то не равно 1, значит логически верно. и будет yes

safocl ★★
() автор топика
Ответ на: комментарий от safocl

а в мане написано чо должно работать именно так.

Покажи мне место в мане, где написано, что test воспринимает аргумент как команду и запускает её?

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

ARR=( pgrep chromium 1>/dev/null )
if [ $ARR ] 
then
echo 'open'
else
echo 'close'
fi

И чего ты ожидаешь?

Если хочешь результат выполнения команды, то $() или `` (последнее не рекомендуется).
if [ "$( pgrep chromium )" ] 
then
echo 'open'
else
echo 'close'
fi
Но, скорее всего тебе нужно не это, так как ты направил stdout в /dev/null

Если хочешь return code, то test вообще не нужен.
if pgrep chromium 1>/dev/null
then
echo 'open'
else
echo 'close'
fi
Так чего тебе нужно?

P. S. И вообще, используй [[...]] вместо [...]

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 3)
Ответ на: комментарий от Kroz

Если хочешь return code, то test вообще не нужен.
if pgrep chromium 1>/dev/null
then
echo 'open'
else
echo 'close'
fi

выше посмотри... такой вариант не выполняется, пишет ошибку

safocl ★★
() автор топика
Ответ на: комментарий от zolden

ага.. несите сразу харчи, а то разгребать долга

safocl ★★
() автор топика
Ответ на: комментарий от aedeph_

в смсле не выведет, у меня пишет ошибку, и данный скрипт всегда отвечает «yes», даже када хромиум не запущен

safocl ★★
() автор топика
Ответ на: комментарий от safocl

данный скрипт всегда отвечает «yes»

Как и должен, согласно man bash, секция CONDITIONAL EXPRESSIONS, случай string и -n string.

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

aedeph_ ★★
()
Ответ на: комментарий от aedeph_

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

у меня с англ проблемы, так как переводит гугл — так я и понимаю

safocl ★★
() автор топика
Ответ на: комментарий от safocl

траббла, роббит, када, сутулится

То есть ты, петушок, считаешь, что с русским у тебя проблем нет?

Ты передаёшь test'у без ключей строку (не команду, не вывод команды, не код возврата, а самую банальную простую строку «pgrep chromium 1>/dev/null»), тест разумеется возвращает 0 (true), как и должен по ману (она, строка, не ненулевой длины), if печатает «yes». Хромиум там в строке или номер твоей карточки test'у без интереса.

Это настолько тривиально, что я всё же рекомендую тебе сильно задуматься о том, так ли тебе это всё надо.

aedeph_ ★★
()
Последнее исправление: aedeph_ (всего исправлений: 1)
Ответ на: комментарий от aedeph_

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

Bash команда test отказывается работать по ману (комментарий)

safocl ★★
() автор топика
Последнее исправление: safocl (всего исправлений: 1)
Ответ на: комментарий от safocl

выше посмотри... такой вариант не выполняется, пишет ошибку

Посмотрел. Не нашел. Если там, где ты берешь это в двойные кавычки, то посмотри внимательней на то, что я писал.

Итог:

$ echo "one
two
three" > file.txt

$ if grep 'two' file.txt 1>/dev/null ; then echo "Найдено" ; else echo "Не найдено"; fi                                        
Найдено

$ if grep 'five' file.txt 1>/dev/null ; then echo "Найдено" ; else echo "Не найдено"; fi
Не найдено

$ grep 'two' file.txt 1>/dev/null
$ if [[ "$?" -eq 0 ]] ; then echo "Найдено" ; else echo "Не найдено"; fi
Найдено

$ grep 'five' file.txt 1>/dev/null
$ if [[ "$?" -eq 0 ]] ; then echo "Найдено" ; else echo "Не найдено"; fi
Не найдено

$ if [[ "$( grep 'two' file.txt )" ]]; then echo "Найдено" ; else echo "Не найдено"; fi
Найдено

$ if [[ "$( grep 'five' file.txt )" ]]; then echo "Найдено" ; else echo "Не найдено"; fi
Не найдено
Ключевые моменты:
- по-максимуму используй кавычки
- внимательно смотри за одинарными и двойными кавычками. На всякий случай, если вдруг не знаешь, основное отличие - внутри двойных кавычек bash будет парсить строку перед тем как передать команде (например, раскрывать переменные), значение в одинарных кавычках всегда будет передаваться как есть.
- не используй обратные кавычки `..` ; вместо этого используй конструкцию $(..). Подробней о преимуществах здесь: http://unix.stackexchange.com/questions/118433/quoting-within-command-substit... . Да, и это не отменяет рекомендации заключать это еще и в двойные кавычки.
- используй [[..]] вместо [..] . Сейчас набегут умники с криками «башизм», но если у тебя нет чётких планов запускать скрипт на каких-нибудь рутерах, и до тех пор пока ты начинаешь файл с !/bin/bash (а не !/bin/sh) - это разумно. И было бы правильно изучить разницу между двумя этими конструкциями: http://stackoverflow.com/questions/3427872/whats-the-difference-between-and-i...
- Не используй конструкцию command1 && command2 || command3 вместо if-then-else-fi: она не всегда правильно отрабатывает. А вот конструкция command1 && command2 - хорошая лаконичная замена if-then-fi (без else) если у тебя одна команда в then-fi

/thread

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 4)
Ответ на: комментарий от Kroz

Не используй конструкцию command1 && command2 || command3 вместо if-then-else-fi: она не всегда правильно отрабатывает.

Обьясните пожалуйста или дайте ссылку, отчего так?

d_a ★★★★★
()
Ответ на: комментарий от d_a
$ true && false || echo "No"
No

command1 && command2 || command3
Если command1 (условие) true, то запустится command2 (пока всё правильно), но если command2 завершится ошибкой, то запустится еще и command3, что неправильно.

Kroz ★★★★★
()
Ответ на: комментарий от d_a

А что если прикостылить?

fail() { echo "Fail"; return 1; }
true && { fail || :; } || echo "Die"

d_a ★★★★★
()
Последнее исправление: d_a (всего исправлений: 1)
Ответ на: комментарий от Kroz

$ if grep 'two' file.txt 1>/dev/null ; then echo «Найдено» ; >>else echo «Не найдено»; fi
Найдено

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

safocl ★★
() автор топика
Ответ на: комментарий от Kroz

- используй [[..]] вместо [..]

да, с ентим уже разобрался, одинарные не понимают множественного вывода, двойные понимают

safocl ★★
() автор топика
Ответ на: комментарий от safocl

называется разыменовывание

Нет это называется parameter substitution, а сами "переменные" в shell называются parameter.

PS. Вынь уже бананы из ушей, отлепи жевачку от пальцев, сходи к логопеду и садись за RTFM, пока тебя не начали репортить с 5.5.

d_a ★★★★★
()
Ответ на: комментарий от safocl

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

1. Команды в двойные кавычки не заключаются. То, что в двойных кавычках - не команды, а строки.
2. Конструкция if command; ... работает не с тем, что команда выводит на экран, а с кодом возврата команды. Поэтому абсолютно всё равно, выводит команда одну строку или несколько.

И вообще, сформулируй нормально вопрос, а еще лучше приведи пример.

P. S.

$ if cat file.txt | grep 'two' 1>/dev/null ; then echo "Найдено" ; else echo "Не найдено"; fi
Найдено

Kroz ★★★★★
()
Ответ на: комментарий от safocl

оно ж возвращает логический код возврата...

Ман нужно до конца курить, а не додумывать. Там есть исчерпывающий перечень конструкций, которые считаются выражениями.

Весь тред не читал, возможно, кто-нибудь тебе уже ответил более подробно.

debugger ★★★★★
()
Последнее исправление: debugger (всего исправлений: 1)
Ответ на: комментарий от safocl

а вот так не работает:

`--> cat upup.sh #! /bin/bash if «pgrep chromium 1>/dev/null» then echo 'yes' else echo 'no' fi

Выложить пароль советовали?

Толсто.

Twissel ★★★★★
()
Ответ на: комментарий от aedeph_

Я таки за бан ТСа.

Странно, что тему не снесли.

Twissel ★★★★★
()
> cat upup.sh
if [ $(pgrep chromium 1>/dev/null) ]; then
        echo 'open'
else
        echo 'close'
fi
> bash upup.sh
close
saahriktu ★★★★★
()
Ответ на: комментарий от Kroz

2. Конструкция if command; ... работает не с тем, что команда выводит на экран, а с кодом возврата команды. Поэтому абсолютно всё равно, выводит команда одну строку или несколько.

а ёпрст, я уже просто спекся, я про [ ] имел ввиду... там без кавычек выводит ошибку...

safocl ★★
() автор топика
Последнее исправление: safocl (всего исправлений: 1)
Ответ на: комментарий от debugger

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

safocl ★★
() автор топика
Ответ на: комментарий от safocl

Так. еще раз, на пальцах.

Любая команда имеет как минимум два результат свое работы:
1. Вывод на экран, на точнее на то, что называется «стандартный вывод», standard out, stdout)
Это то, что ты видишь на экране когда команда работает.
Это то, что ты перенаправляешь конструкцией > (или 1> что то же); например ls > "filename.txt".
Это то, что ты подаешь на вход (стандартный ввод, standard in, stdin) другой команды с помощью |; например ls | grep 'image.jpg', ls | grep 'image.jpg' > "filename.txt"
Это то, что можно записать в переменную с помощью $(...) ; например A="$(ls)", A="$( ls | grep 'image.jpg' )

2. Код возврата. В bash он записывается в специальную переменную $?. То есть ты его можешь увидеть только запустив echo "$?" сразу после выполнения команды

if работает с кодом возврата. Он запускает команду, которую ты после него пишешь, и работает с кодом возврата. Считается что 0 это true (ИСТИНА), не-0 false (ЛОЖЬ)
if не работает с числами
- if 0; then ... выведет ошибку, потому что воспримет 1 как команду, которую нужно запустит, а такой команды нет, и будет ошибка.
if не работает с выводом команды
- if echo 1; then ... всегда будет истинным, так как команда echo будет завершаться успешно, и не важно что она выводит не-ноль.
if не работает с переменными.
- if A; then ... fi выведет ошибку, потому что команды A в системе нет.
if не работает со строками.
- if $A; then ... fi попытается взять команду из переменной A и запустить её.
if не работает со строками.
- if "some text" выведет ошибку, так как он будет искать команду some text (именно так, с пробелом), не найдет её, и напишет что не нашел.
- if some text ... попытается запустить команду some и передать ей параметр text.
- if (some text) аналогичен if some text

[ или test работает со строками и числами. Результат работы ее - код возврата, именно то, что нужно if. она нужна для того, чтобы делать ветвления на основе сравнения строк и чисел.
[ не работает с командами
- [ ls ] даст 0 (true), так как воспримет ls как строку, а если нет оператора сравнения, то не-пустая строка дает true.
- [ "" ] даст 1 (так как строка пустая)
- [ echo 1 ], как и [ pgrep chromium ] выведет ошибку, так как ты задал две строки: «pgrep» и «chromium», нет оператора сравнения, и непонятно что с этим делать.

Конструкция $(..) - это конструкция bash (не test, не if - bash), которая позволяет «запихнуть» вывод команды в строку.
Например:

$ A="ls"
$ echo "$A"
ls
$ A="$(ls)"
$ echo "$A"
# Вывод ls, который был в переменной
Конструкция [ pgrep chromium ] , как уже говорилось, выведет ошибку
Конструкция [ "$( pgrep chromium )" ] запустит pgrep chromium, и вывод этой команды передаст test в качестве аргумента. Если процесс chromium найден, то pgrep chromium выведет id процесса, для test это будет не-пустая строка, и test вернет true. Если процесс chromium не найден, то pgrep chromium выведет пустоту, которая будет передана test, в ответ на «пустоту» test вернет false. Да, это может быть использовано для конструкции if [ "$( pgrep chromium )" ]. Но вместе с пустым выводом у pgrep будет код возврата 1, то есть false. Так что if [ "$( pgrep chromium )" ] полностью аналогична if pgrep chromium.

Я не знаю куда уже детальней.

Kroz ★★★★★
()
Ответ на: комментарий от Kroz

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

при чем не надо путать линукс и баш...

вообще линукс и основался благодаря энтузиазму, чо челы друг другу помагали, кто то в том плане лучше разобрался, кто то в другом, передавая друг другу все наработки, без ентого бы и не было СПО в принцыпе... Ентож и есть концепция СПО — разработка сообществом

safocl ★★
() автор топика
Последнее исправление: safocl (всего исправлений: 2)
Ответ на: комментарий от safocl

так почему же
if $(pgrep chromium >/dev/null)
нормально работает?

Я хз посему оно работает. Ровно как и не знаю почему работает такое:

$ A=""; if $A ; then echo "yes" ; else echo "no"; fi
yes
В любом случае это что-то странное, не используй это, если не хочешь запутаться.

Kroz ★★★★★
()
Ответ на: комментарий от safocl

Дело не в том. Наиболее актуальная инфа есть только на английском. Русские переводы обычно запаздывают и есть далеко не по всем вопросам.

Kroz ★★★★★
()
Ответ на: комментарий от Kroz

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

safocl ★★
() автор топика
Ответ на: комментарий от surefire

хммм... ты чота меня савсем запутал...

safocl ★★
() автор топика
Ответ на: комментарий от safocl

да не смогу я его докурить, я ж объяснял чо в англ не особо...

В гугле забанили? Русский ман на команду тест трудно было найти?

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

Если б ты понимал буквально, проблем бы не было, а ты выдумываешь.

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

Сдаётся мне что ты здесь специально дурачка валяешь, поэтому воспользуюсь твоим советом.

debugger ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.