bash, чтобы проверить, имеет ли вход @

Это зависит от того, как вы создаете пакет. dpkg-buildpackage не вызывает цель clean, если вы передадите ей параметр -nc. Другим полезным вариантом для сборки теста является -uc (не подписывать файл изменений). debuild наследует эти параметры из dpkg-buildpackage.

Для тестовой сборки вы можете просто сделать fakeroot debian/rules binary (настроить цель, подходящую для многобайтового пакета).

1
задан 2 November 2014 в 04:22

3 ответа

Хотя у вас есть возможность использовать встроенные функции оболочки, чтобы проверить, содержит ли вход пользователя @ (который хорошо документирован в других ответах), другой разумный способ сделать это с помощью внешней утилиты grep: [ ! d0]

#!/usr/bin/env bash

read -erp '> '
if grep -q @ <<<"$REPLY"; then
    echo pass
else
    echo fail
fi

Передача флага -q в grep предотвращает печать совпадающих строк. (Он также не позволяет читать больше строк после поиска совпадения, но это не имеет никакого значения здесь, поскольку есть только одна строка ввода.)

Заманчиво сократить конструкцию if к чему-то вроде grep -q @ <<<"$REPLY" && echo pass || echo fail, но я сознательно избегал этого:

В этом случае это, вероятно, все в порядке, поскольку единственный способ, которым печатает неправильное слово, - это pass должно быть напечатано и [ f12] не удалось распечатать его. Затем, предположительно, эхо не будет печатать fail. Хотя короткое замыкание && и || часто являются подходящими (и я часто использую их для сокращения if без предложения else), используя их вместе, как если бы они были тройными, если оператор на самом деле не является хорошая привычка. Хотя некоторые команды не могут потерпеть неудачу, возможно echo. Если пользователь перенаправляет вывод своего сценария на невоспроизводимый файл или устройство или использует его в разбитом конвейере, эхо и другие команды, которые выводят текст, могут возвращать сбой, в результате чего выражение && терпит неудачу, а правая сторона || выражение для выполнения. Вы можете протестировать поведение сценария при наличии неназываемого устройства вывода, запустив его с помощью >/dev/full.

Этот скрипт использует несколько функций bash:

В этом случае это, вероятно, хорошо, поскольку единственный способ, которым печатает неправильное слово, - это pass напечатано и echo не удалось распечатать его. Затем, предположительно, эхо не сможет распечатать fail. В bash read автоматически помещает вход пользователя в переменную REPLY, если не указана переменная. Хотя короткое замыкание && и || часто являются подходящими (и я часто использую их для сокращения if без предложения else), используя их вместе, как если бы они были тройными, если оператор не очень хорошая привычка. Хотя некоторые команды не могут потерпеть неудачу, echo может. Bash и без других оболочек стиля Bourne, таких как dash, принимают -p. Но тройной, если оператор . А в некоторых, как ksh, -p имеет другое значение. (Спасибо geirha за то, что он указывает fail и что это не всегда означает «подсказка».)

Если вы хотите, чтобы сценарий был переносимым на другие ОС, не устанавливайте bash, вы можете использовать:

#!/bin/sh

printf '> '
read -r line

if printf '%s' "$line" | grep -q @; then
    echo pass
else
    echo fail
fi

Если хотите, вы можете пропустить сохранение ввода пользователя в переменной, прочитав его с помощью grep вместо [ f32]:

#!/bin/sh

printf '> '
if head -1 | grep -q @; then
    echo pass
else
    echo fail
fi

Как упоминал Geirha, head -n 1 можно считать лучшим синтаксисом, поскольку head -1 официально устарел (хотя текущие sed реализации или, по крайней мере, GNU sed, поддерживают -1 в своих последних версиях, в то время как некоторые очень старые sed реализации не поддерживают -n 1).

Как сказал geirha , вы можете использовать sed вместо максимальной переносимости .

#!/bin/sh

printf '> '
if sed 1q | grep -q @; then
    echo pass
else
    echo fail
fi
1
ответ дан 24 May 2018 в 02:15

Предпочтительным способом в bash является использование функции сопоставления паттерна [[ ... ]].

#bash
read -rp "Input: " input
if [[ $input = *@* ]]; then
    printf '<%s> contains @\n' "$input"
fi

Вместо скриптов sh вы можете использовать case.

#sh
printf 'Input: '
read -r input
case $input in
    *@*) printf '<%s> contains @\n' "$input" ;;
esac

См. также главу «Тесты и условные обозначения» в руководстве Bash.

0
ответ дан 24 May 2018 в 02:15

В более новых версиях bash вы должны иметь возможность использовать регулярное выражение с помощью расширенного тестового оператора =~:

$ read -p "input: " input
input: quertyuiop 
$ if [[ $input =~ \@ ]]; then echo "match"; else echo "no match"; fi
no match
$ 
$ read -p "input: " input
input: qwerty@uiop
$ if [[ $input =~ \@ ]]; then echo "match"; else echo "no match"; fi
match

Альтернативой, которая должна работать в любой POSIX-совместимой системе, является использовать expr, например в оболочке dash:

$ read input
qwertyuiop
$ if expr "$input" : '.*@.*' > /dev/null; then echo 'match'; else echo 'no match'; fi
no match
$ 
$ read input
qwerty@uiop
$ if expr "$input" : '.*@.*' > /dev/null; then echo 'match'; else echo 'no match'; fi
match
$ 
-1
ответ дан 24 May 2018 в 02:15
  • 1
    Привет, ребята! Вы мне много о чем подумали! – JONAS402 2 November 2014 в 18:16
  • 2
    Я был бы прав, сказав, что могу использовать эти выражения некоторое время или до цикла? – JONAS402 2 November 2014 в 19:48

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

Похожие вопросы: