Почему кажется, что команда «найти» в Alpine требует экранирования «?» а не на убунту?

ответ Джорданма неверен. /etc/profileне является источником всех оболочек. Как вы указываете, это не источник csh, tcsh-. Я не уверен насчет zsh. Его источником являются производные оболочки Bourne (sh), такие как Korn Shell(ksh)и BASH (bash). cshиспользует /etc/login. Люди, которые склонны использовать исключительно производные оболочки Borne Shell, как правило, забывают о существовании других оболочек. Они добавляют что-то к /etc/profile, ожидая, что это будет применяться ко «всем пользователям», а затем удивляются, когда странный пользователь C Shell (и мы — нечетная группа )не имеют того, что они настроили в /etc/profile..

Несмотря на это, люди склонны забывать о других существующих оболочках, производных от Borne Shell. Если они используют bashили ksh, они могут свободно добавлять в /etc/profileсинтаксис, недопустимый в Bourne Shell, например, определение переменной и ее экспорт в той же строке. Затем вы получаете сценарий, который выполняет #!/bin/shи задыхается от синтаксиса. /etc/profileдолжен придерживаться синтаксиса, совместимого с Bourne Shell.

Аналогично,вы должны придерживаться его в своем собственном.profile(использовать .bash_profile, если вам нужен синтаксис bash)-это может быть немного больше набора текста, но это дополнительный набор текста, который вы делаете один раз. Ссылка ${HOME}, а не ~и т. д. Некоторые разновидности Unix, задания cron выполняются под sh, каждая строка вашего Makefileобрабатывается sh, поэтому, если вы работаете с несколькими разновидностями UNIX, действительно стоит поддерживать совместимость с оболочкой .profileBourne. Как системный администратор, я не могу сказать вам, сколько раз я помогал кому-то, исправляя их .profileдля совместимости с Bourne Shell.

В Linux /bin/shявляется ссылкой на /bin/bash, и когда вы запускаете его, он выглядит как путь, который использовался для его запуска, и (теоретически )ограничивается только тем, что Bourne Шелл поддерживает. Точно так же viв Linux на самом деле vim, опять же самоограничение. Иногда вы видите, что функции «просачиваются». Иногда vim, выдавая себя за vi, делает что-то, что vimподдерживает, а viнет, потому что авторы vimзабыли отключить это в режиме "обратной совместимости vi". Я не удивлюсь, если у bash, притворяющегося sh, есть некоторые похожие черты «просачивания». Не удивлюсь, если какая-то функция «работает в Borne Shell в Linux», но не в UNIX на основе System V или BSD (, AIX, OpenBSD и т. д. ).

5
30.11.2021, 09:26
1 ответ

Они используют разный синтаксис для регулярных выражений .

GNU find-regexиспользует регулярные выражения Emacs по умолчанию. Это можно изменить с помощью опции -regextype, специфичной для GNU find; другие варианты включают базовые регулярные выражения POSIX BRE (, такие как grep и sed ), и расширенные регулярные выражения POSIX ERE (, такие как grep -Eи (почти )awk ).

BusyBox find-regexиспользует POSIX BRE (по умолчанию для функцииregexc). Поскольку BusyBox спроектирован так, чтобы быть небольшим, нет возможности использовать другой синтаксис регулярных выражений.

FreeBSD , macOS и NetBSD по умолчанию используют BRE и могут использовать ERE с параметром -E.

POSIX не стандартизирует -regex.

Для вашей команды:

  • В BRE (basic )группировка \(…\). Нулевой -или -один оператор равен \?, если он присутствует, но это необязательная функция, присутствующая в BusyBox при сборке с Glibc (. Я не уверен в других libc ), но не в BSD.. Ноль -или -также можно записать как \{0,1\}.
  • В Emacs RE группировка — это \(…\), а нулевой -или -единичный оператор — это ?. Хотя сам Emacs также поддерживает \{0,1\}для обозначения нуля -или -единицы, синтаксис регулярных выражений Emacs GNU find этого не делает.
  • В расширенном )ERE (группировка — это (…), а нулевой -или -один оператор — это ?.

Если вам нужна переносимость между различными реализациями find, которые реализуют -regex, вам нужно придерживаться конструкций POSIX BRE (ради BusyBox ), которые пишутся одинаково в синтаксисе Emacs GNU find.. Это означает, что нет нулевого -или -одного оператора.

find./frontend -mindepth 1 \( -regex '^./dir1/dir2/.*' -o -regex '^./dir1/dir2' \)

Или, в качестве альтернативы, организовать передачу -regextype posix-basicв GNU find.

case $(find --help 2>/dev/null) in
  *-regextype*) find_options='-regextype posix-basic';;
  *) find_options=;;
esac
find./frontend $find_options -mindepth 1 -regex '^./dir1/dir2\(/.*\)\{0,1\}'

Если dir1и dir2являются простыми строками, а не регулярными выражениями,вы не получаете никакой пользы от -regex, и вы можете просто написать

find./frontend/dir1/dir2 -maxdepth 1
7
30.11.2021, 10:58

Теги

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