Bashでは、文字列に含まれるパスがリモートの場所を指していることを確認する必要があります。以下は効果がありませんsome code
。実行されません。test
( )コマンドでワイルドカードがどのように[
機能するかについていくつかの情報が欠けているようですが、何がわかりません。マニュアルページは私には役に立ちません。私は何が間違っていましたか?この問題をどのように解決するのですか?
path="user@host:/home/user"
if [ "$path" == ?*"@"?*":"?* ]; then
some code
fi
答え1
コマンド[
はコマンドであり、他のコマンドに解析されます。これは次のことを意味します。
[ "$path" == ?*"@"?*":"?* ]
globとして扱われるので、?*"@"?*":"?*
パターンと一致する現在のディレクトリのファイルリストに展開されます(現在のディレクトリのファイルリストに展開されるのと同じ*.txt
)。txt
次のように書いても:
[ "$path" == '?*@?*:?*' ]
ワイルドカードを防ぐために、コマンドの==
演算子(非標準バージョン)がパターン一致演算子ではなく文字列同等演算子であるため、これは機能しません。=
[
パターンマッチングを実行するには、以下をサポートするksh
-style[[ x = pattern ]]
パターンマッチング演算子を使用できます。bash
zsh
path="user@host:/home/user"
if [[ "$path" = ?*@?*:* ]]; then
some code
fi
あるいは、より良い方法はPOSIX / Bournesh
case
設定を使用することです。
case $path in
?*@?*:*) some code
esac
これによりインストールする必要がなく、bash
システム標準を使用してsh
スクリプトを解釈できます。
これもuser@host:/home/user
有効です。地元のpath(try)を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
パスがリモートであることを確認するのと同じことを行うにはまだ十分ではありません。見ているOpenSSHscp
コード、左側にnoがあり、下にないパスが含まれていて、開始せずに含まれて:
いる場合、パスはリモートパスです。もちろん、ユーザーとホスト部分は空であるため、正しく機能しない可能性があります。:
(中間に残らない)またはローカルパス(内部)。/
[...]
[::1]
[...]
@
x:
@:
user@[::1/64]:/x
/
:
[...]
[foo@bar:/path
:
[...]
これをPOSIXcase
文と一致させることは不可能です。正規表現を一致させるには、などのラップアラウンド演算子をサポートする正規表現を使用する方がやや簡単ですperl
。これをサポートします(zsh
PCREライブラリの使用、自己実装の使用)。ksh93
zsh
ksh93
zsh
:set -o rematchpcre remote='^(?!:)(?:(?!\[)[^/:]*@)?(?:\[(?:(?!]:)[^/])*\]|(?!\[)[^/:]*):' if [[ $path =~ $remote ]]; then some code fi
ksh93
:remote='(?P:^(?!:)(?:(?!\[)[^/:]*@)?(?:\[(?:(?!]:)[^/])*\]|(?!\[)[^/:]*):)' if [[ $path =~ $remote ]]; then some code fi
(単純化できれば驚かないでしょう)。