ファイルマッチパターン!(*例)は、bashシェルとbashスクリプトで異なる動作をします。

ファイルマッチパターン!(*例)は、bashシェルとbashスクリプトで異なる動作をします。

bash端末に直接貼り付けると、次のようになります(bash、bashバージョンを明示的に呼び出します4.4.19(1)-release (x86_64-pc-linux-gnu)

for filename in /home/dean/Downloads/!(*example).txt; do
    echo "${filename}"
done

このコマンドは、ファイル名に「example」が含まれていないすべてのtxtファイルをエコーし​​ます。

しかし、それを名前の付いたスクリプトに変換し、temp.shchmod +x temp.shのように呼び出すと./temp.sh

#!/usr/bin/env bash

for filename in /home/dean/Downloads/!(*example).txt; do
    echo "${filename}"
done

次のエラーが発生します。

dean@dean-thinkpad-p52s:~/Downloads$ ./temp.sh 
./temp.sh: line 3: syntax error near unexpected token `('
./temp.sh: line 3: `for filename in /home/dean/Downloads/!(*example).txt; do'

私はここで問題を理解していません。シェルでは私が望むことを正確に実行しますが、スクリプトでは何もしません。

編集(回答半期問題):

envシェル/ターミナルから呼び出すときとenvシェル/スクリプトで呼び出すときの違いは次のとおりです。

dean@dean-thinkpad-p52s:~/Downloads$ diff example_myshell.txt example_called_script.txt 
5a6
> _=/usr/bin/env
36,37d36
< TERM=xterm-256color
< SHELL=/bin/bash
38a38,39
> SHELL=/bin/bash
> TERM=xterm-256color
45c46
< PYENV_SHELL=bash
---
> SHLVL=4
47c48
< SHLVL=3
---
> PYENV_SHELL=bash
61d61
< _=/usr/bin/env

ベストアンサー1

Kornシェルスプレッド演算子は、このオプションをオンにした場合にのみ使用できます!(...)(デフォルトではオフ)。bashextglob

extglobインタラクティブシェルから別の初期化ファイルを渡したか開いた可能性がありますが、~/.bashrcこれらのファイルはスクリプトの実行時にインポートされず、オプションは呼び出しシェルから継承されません(BASHOPTS環境内の変数ではない限り)。そこに置くのは悪い考えです)。

明示的に開く

shopt -s extglob

スクリプトの冒頭で動作するはずです。

まだshopt -s extglob解析されていない次の行からのみ有効です。これは、サブシェルでのみ拡張モードをオンにするためにshopt -s extgloblikeを使用できないことを意味します。set -f

# this won't work
(
  shopt -s extglob
  echo !(no such file)
)

次の作業を行う必要があります。

(
  shopt -s extglob
  eval 'echo !(no such file)'
)

おすすめ記事