Нет, поскольку вывод не дублируется. Чтобы продублировать файловые дескрипторы, вы также должны дважды вывести на них.
Хотя можно и с циклом, вот так:
while read l
do
echo "$l" >&3
echo "$l" >&4
done
С бинарными данными будут глючить (нули выбиты, crlf -s будут преобразованы в lf ).
Ваш пример сделал это:
Перенаправление, по сути, является клоном, в терминологии Unix,это как жесткая ссылка. С суффиксом 3>&1
к команде у вас будут fd 3 и fd 1, указывающие на один и тот же объект (, который теперьfile
).
Если у вас есть некоторое сходство с C, я хотел бы проверить man 3 dup2
, это именно то, что делает перенаправление fd.
Используйте оператор =~
для сравнения регулярных выражений:
#!/bin/bash
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file =~ $testseq ]];
then
echo "True"
else
echo "False"
fi
Таким образом, он будет сравнивать, если $file
содержит $testseq
.
user@host:~$ ./string.sh
False
Если я изменю testseq="Const"
:
user@host:~$ ./string.sh
True
Но будьте осторожны с тем, что вы кормите $testseq
. Если строка на нем каким-то образом представляет собой регулярное выражение (например, [0-9]
), есть больше шансов вызвать «совпадение».
Ссылка:
Вам необходимо интерполировать переменную $testseq
одним из следующих способов:
$file == *_"$testseq"_*
(здесь $testseq
рассматривается как фиксированная строка)
$file == *_${testseq}_*
(здесь $testseq
рассматривается как шаблон ).
Или _
сразу после имени переменной будет считаться частью имени переменной (это допустимый символ в имени переменной ).
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
case "$file" in
*_"$testseq"_*) echo 'True' ;;
*) echo 'False'
esac
Использование case... esac
— один из самых простых способов выполнить сопоставление с образцом переносимым способом. В других языках он работает как оператор «switch» (bash
, zsh
и ksh93
, а также позволяет вам переходить -через различными несовместимыми способами ). Используемые шаблоны являются стандартными шаблонами подстановки имен файлов.
Проблема связана с тем, что _
является допустимым символом в имени переменной. Таким образом, оболочка увидит *_$testseq_*
как «*_
, за которым следует значение переменной $testseq_
и *
». Переменная $testseq_
не определена, поэтому она будет расширена до пустой строки, и вы получите *_*
, что, очевидно, соответствует имеющемуся у вас значению $file
. Вы можете ожидать получить True
, если имя файла в $file
содержит хотя бы одно подчеркивание.
Чтобы правильно разграничить имя переменной, используйте "..."
вокруг расширения:*_"$testseq"_*
.Это будет использовать значение переменной в виде строки. Если вы хотите использовать значение переменной как шаблон , используйте вместо этого *_${testseq}_*
.
Еще одним быстрым решением является включение символов подчеркивания в значение$testseq
:
testseq="_gen_"
, а затем просто используйте *"$testseq"*
в качестве шаблона (для сравнения строк ).
Для портативного способа проверить, содержит ли строка подстроку, используйте:
file="JetConst_reco_allconst_4j2t.png"; testseq="gen"
[ "${file##*$testseq*}" ] || echo True Substring is present
Или "${file##*"$testseq"*}"
, чтобы избежать интерпретации символов подстановки в testseq
.