Библиотеки XMLSECURITY
# yum search xmlsec
.
xmlsec1
xmlsec1-devel
xmlsec1-gcrypt
xmlsec1-gcrypt-devel
xmlsec1-gnutls
xmlsec1-gnutls-devel
xmlsec1-nss
xmlsec1-nss-devel
xmlsec1-openssl
xmlsec1-openssl-devel
В списке строк -http://mirror.centos.org/altarch/7.4.1708/os/i386/Packages/
Пример установки:# yum install xmlsec1-devel
Основная проблема заключается в том, что вы используете сопоставление с образцом в [[... ]]
в сценарии, выполняемом /bin/sh
, который не поддерживает эти типы тестов. См. также вопрос, озаглавленный Сценарий оболочки выдает ошибку «не найдено» при запуске из файла sh. Но при ручном вводе команды работают
Другая проблема заключается в том, что вы объединяете вывод ls
в одну строку, прежде чем разбивать ее на слова по пробелам, табуляциям и символам новой строки, а также применять подстановку имен файлов к сгенерированным словам. Затем вы перебираете результат этого.
Вместо:
#!/bin/sh
cd Folder || exit 1
for name in *b*; do
[ -e "$name" ] || [ -L "$name" ] || continue
case $name in (*a*) ;; (*) printf '%s\n' "$name"; esac
done
Это перебирает все файлы в каталоге Folder
, в которых есть буква b
, а затем печатает те из них, которые не содержат a
. Проверка символа a
выполняется с помощью case... esac
.Шаблон *a*
соответствует символу a
в имени файла, если он есть, и в этом случае ничего не происходит. Операторы printf
находятся в «случай по умолчанию», который выполняется, если в строке нет a
.
Тесты с -e
и -L
нужны для того, чтобы убедиться, что мы поймаем пограничный случай, когда шаблон цикла ничему не соответствует. В этом случае шаблон останется нерасширенным, поэтому, чтобы убедиться, что мы можем отличить нерасширенный шаблон от реального существующего файла, мы проверяем его с помощью -e
. Тест -L
состоит в том, чтобы поймать еще один пограничный случай символической ссылки, которая имеет то же имя, что и шаблон цикла, но не указывает ни на что допустимое. Приведенный ниже код bash
не нуждается в этом, потому что он использует параметр оболочки nullglob
вместо (, недоступного в /bin/sh
).
Запуск цикла по расширению шаблона *b*
вместо любого результата ls
имеет то преимущество, что он также может работать с именами файлов, содержащими пробелы, табуляции, символы новой строки и символы подстановки имени файла (имена файлов никогда не помещайте в одну строку, которую мы затем пытаемся перебрать ).
В оболочке bash
вы можете сделать то же самое с [[... ]]
тестом сопоставления с образцом, как вы пытались сделать сами:
#!/bin/bash
cd Folder || exit 1
shopt -s nullglob
for name in *b*; do
[[ $name != *a* ]] && printf '%s\n' "$name"
done
См. также:
Чтобы напечатать имена файлов в Folder
, которые содержат b
, а не a
, в zsh
и его ~
(, за исключением /и -, а не)оператор glob:
#! /bin/zsh -
set -o extendedglob
print -rC1 -- Folder/(*b*~*a*)(N:t)
(удалитеN
(для nullglob
, если вы хотите, чтобы сообщалось об ошибке, когда нет соответствующего файла ).
Вksh93
(оболочке, которая представила этот [[...]]
оператор (, который не является частью стандартного sh
синтаксиса ), а его&
(и)и!(...)
(не)операторы:
#! /bin/ksh93 -
(
CDPATH= cd Folder &&
set -- ~(N)@(*b*&!(*a*)) &&
(($# > 0)) &&
printf '%s\n' "$@"
)
В оболочке bash
(, которая, как и zsh
, также скопировала оператор [[...]]
ksh ), используя extglob
для поддержки операторов glob ksh88 и nullglob
для получения эффекта от N
zsh. ] квалификатор glob или ksh93
оператор glob ~(N)
и некоторое двойное отрицание с|
(или)для достижения и:
#! /bin/bash -
(
shopt -s extglob nullglob
cd./Folder &&
set -- !(!(*b*)|*a*) &&
(($# > 0)) &&
printf '%s\n' "$@"
)
В стандартном синтаксисе sh
:
#! /bin/sh -
(
CDPATH= cd Folder || exit
set -- [*]b[*] *b*
[ "$1/$2" = '[*]b[*]/*b*' ] && exit # detect the case where the pattern
# expands to itself because there's
# no match as there's no nullglob
# equivalent in sh
shift
for i do
case $i in
(*a*) ;;
(*) set -- "$@" "$i"
esac
shift
done
[ "$#" -gt 0 ] && printf '%s\n' "$@"
)
Обратите внимание, что решения, использующие cd
, не будут работать, если у вас есть доступ для чтения к Folder
, но нет доступа к нему для поиска.
В более общем смысле, чтобы ответить на общий вопрос о том, как проверить, содержит ли строка другую строку в sh
, лучше всего использовать конструкцию case
, которая используется для сопоставления с образцом в sh
. Вы даже можете использовать вспомогательную функцию:
contains()
case "$1" in
(*"$2"*) true;;
(*) false;;
esac
Использовать как если бы:
if contains foobar o; then
echo foobar contains o
fi
if ! contains foobar z; then
echo foobar does not contain o
fi
if
contains "$file" b &&
! contains "$file" a
then
printf '%s\n' "$file contains b and not a "
fi