Программа login
наборы MAIL
переменная окружения, когда Вы входите в виртуальную консоль Linux.
От login(1)
страница справочника:
Значение за $HOME, $USER, $SHELL, $PATH, $LOGNAME и $MAIL установлено согласно соответствующим полям во вводе пароля.
login
программа, используемая для запуска сессии, когда Вы входите в виртуальную консоль Linux. Это предлагает Вам имя пользователя и пароль, устанавливает некоторые основные переменные окружения и запускает оболочку.
Если Вы используете графического менеджера по входу в систему (например, один предоставленный с Gnome или KDE) вместо login
, MAIL
переменная окружения не может быть установлена.
Bash обычно только дает почтовые уведомления, когда он используется в качестве оболочки входа в систему. Даже если MAIL
переменная окружения установлена, нормальный интерактивный экземпляр bash
в xterm
или konsole
не отобразит почтовое уведомление.
Можно работать bash
с -l
отметьте, чтобы вынудить это вести себя как оболочка входа в систему. Можно передать xterm
-ls
флаг, чтобы заставить его запустить Вашу оболочку как оболочку входа в систему.
Если вы можете полагаться на встроенные регулярные выражения Bash (а именно на оператор =~
) и переменные массива, вы можете использовать нечто подобное:
#!/bin/bash
W1=( $( echo "$1" | sed "s/./\n&/g" | sort -u ) )
W2="$2"
set ${W1[*]}
while [[ ! -z "$1" ]]; do
if [[ "$W2" =~ "$1" ]]; then
printf "$1 "
fi
shift
done
printf "\n"
В первой строке создается массив, который содержит каждый символ, содержащийся в $1
. Затем сохраняется $2
, а затем позиционные параметры устанавливаются на значения элементов $W1
. Затем каждый символ (теперь позиционный параметр) сопоставляется с сохраненным вторым словом и, если совпадение найдено, выводится. Наконец, позиционные параметры сдвигаются таким образом, что цикл продолжается со следующим символом.
Концепции, которые можно увидеть здесь: работа с массивом, захват вывода команды в переменную, изменение позиционных аргументов, цикл и условный оператор.
Если вы хотите сделать это просто, вы можете рассмотреть, например, эту (на самом деле это разделение на один лайнер для большей читабельности):
#!/bin/bash
printf "$1" \
| sed "s/./\n&/g" | sort -u \
| grep -F "$( printf "$2" | sed 's/./&\n/g' | sort -u )"
Сортировка sed | сортирует -u
комбо просто разбивает слова на один уникальный символ в форме строки. grep -F
рассматривает параметр (здесь разбитое второе слово) как фиксированные строки, которые должны быть сопоставлены во входных данных, и таким образом пытается сопоставить каждый символ в $1
с каждым символом в $2
. В реальных ситуациях Вы, вероятно, удалите вторую сортировку | uniq
, так как "слова" обычно довольно короткие, и любой прирост производительности будет уничтожен путем порождения двух дополнительных процессов. Однако, так как $2
становится больше (сотни или тысячи строк), Вы определенно хотите сделать любую возможную оптимизацию.
Вы также можете заменить команду sed
на fold -w 1
, которая делает почти то же самое (она короче для набора, но команда sed
s
- это нож швейцарской армии для обработки текста).
Ниже приводится простой подход, который выполняет итерацию по первой строке и проверяет, присутствует ли каждый символ во второй строке. Если символ присутствует, он напечатает его на консоли.
str1=$1;
i=0
while [ $i -ne ${#str1} ]
do
c=${str1:$i:1}
if [[ $2 == *$c* ]]
then
echo $c
fi
((i++))
done
Если вам нравятся маленькие одиночные ссылки, и вы не против пользоваться общими инструментами из GNU coreutils, то вы можете сделать что-нибудь вроде этого:
comm -12 <( fold -w1 <<< "$1" | sort -u ) <( fold -w1 <<< "$2" | sort -u )
Если вас не волнует регистр букв, вы можете поменять $1
и $2
на ${1,,}
и ${2,,}
соответственно.
Помимо утилит comm
, fold
и sort
, в них используются <( )
командные substiutions и <<<
here-strings.
В качестве альтернативы, если вы хотите получить чистый bash-ответ (без кореша) и хотите получить больше возможностей для работы с различными bash-функциями, вот еще:
declare -A arr
for (( i=0; i<${#1}; i++ )); do
(( arr[${1:i:1}] |= 1 ))
done
for (( i=0; i<${#2}; i++ )); do
(( arr[${2:i:1}] |= 2 ))
done
for i in ${!arr[@]}; do
if (( ${arr[$i]} == 3 )); then
echo $i
fi
done
В этом случае используется ассоциативный массив bash , поэтому требуется версия 4 или более поздняя.
Он также использует (( ))
арифметические расширения с битовой арифметикой.
Оно работает через символы первой строки и использует каждый из них как индекс в ассоциативном массиве. Элемент, соответствующий этому индексу, имеет значение ORed с 1 (или имеет свой бит 0).
То же самое происходит и со второй строкой, за исключением того, что элемент имеет значение 2 (или имеет свой бит 1).
Затем мы проходим по массиву в поисках элементов, имеющих биты 0 и 1 (т.е. равные 3), и выводим индекс (который является общей буквой).