Назначьте идентификатор переменной в цикле и отобразите его значение

Команда [ команда и анализируется как любая другая команда. Это означает, что в:

[ "$path" == ?*"@"?*":"?* ]

? * "@"? * ":"? * рассматривается как глобус, поэтому он расширяется до списка файлов в текущем каталоге, которые соответствуют этому шаблону (просто например, *. txt расширяется до списка файлов txt в текущем каталоге).

Даже если бы вы написали это:

[ "$path" == '?*@?*:?*' ]

для предотвращения подстановки, это не сработает как оператор == (нестандартная версия = ) оператора [] - это просто оператор равенства строк, а не оператор сопоставления с образцом.

Чтобы выполнить сопоставление с образцом, вы можете использовать ksh -стайл [[x = образец]] оператор сопоставления с образцом, который bash и zsh также поддерживает:

path="user@host:/home/user"
if [[ "$path" = ?*@?*:* ]]; then
  some code
fi

Или, что еще лучше, используйте конструкцию POSIX / Bourne sh case :

case $path in
  ?*@?*:*) some code
esac

Таким образом, вам даже не нужно иметь bash , вы можете использовать системный стандарт sh для интерпретации вашего скрипта.

Обратите внимание, что user @ host: / home / user также является допустимым локальным путем (попробуйте mkdir -p user @ host: / home / user ), хотя с scp вам нужно будет передать его как ./ user @ host: / home / user , чтобы он не рассматривался как удаленный путь. Поэтому вы можете уточнить свой тест до:

case ${path%%@?*:*} in
  (*/* | "$path" | "") echo not a remote path;;
  (*) echo remote path;;
esac

Чтобы ./ x @ y: z не рассматривался как удаленный путь.

Этого все еще недостаточно, чтобы сделать то же самое, что и scp , чтобы решить, является ли путь удаленным или нет. Если посмотреть на OpenSSH scp код , путь будет удаленным, если он не начинается с : и если он содержит : без / слева от него, и это не внутри [...] (для адресов IPv6, таких как [:: 1] . За исключением тех [...] рассматриваются только в позиции хоста (в начале или после @ ).Так, например, x: , @: - это удаленные пути (хотя, очевидно, часть пользователя и хоста пуста, что, скорее всего, не будет работать должным образом) и user @ [:: 1/64]: / x ( / слева от : , который не находится между [...] ) или [ foo @ bar: / path - это локальные пути (: находится внутри [...] ).

Было бы невозможно сопоставить это с одним оператором case POSIX . Чтобы сопоставить с одним регулярным выражением, было бы немного проще с регулярными выражениями, которые поддерживают такие операторы, как perl . zsh и ksh93 поддерживают их ( zsh с использованием библиотеки PCRE, ksh93 с использованием собственной реализации).

  • zsh :

     set -o rematchpcre 
    remote = '^ (?!:) (?: (?! \ [) [^ /:] * @)? (?: \ [(?: (?!]:) [^ /]) * \] | (?! \ [) [^ /:] *): '
    if [[$ path = ~ $ remote] ]; затем 
    какой-нибудь код 
    fi 
     
  • ksh93 :

     remote = '(? P: ^ (?!:) (?: (?! \ [) [^ /:] * @)? (?: \ [(?: (?!]:) [^ /]) * \] | (?! \ [) [^ /:] *) :) ' 
    если [[$ path = ~ $ remote]]; затем 
    какой-нибудь код 
    fi 
     

(я не удивлюсь, если его можно упростить).

2
08.07.2015, 02:05
0 ответов

Теги

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