関数内の変数の定義

関数内の変数の定義

このインターネットのどこかで読んだ後、コマンド出力を変数として使用するときは、次のことを行うのが最善です。

FILE_CORE_NAME="$(/usr/bin/env basename $(/usr/bin/env awk -F "." '{print $1}' <<< "${FILE_TO_PROCESS}"))"; local FILE_CORE_NAME;

ただし、この構成では、FILE_CORE_NAMEから派生した値は空です。local FILE_CORE_NAME行から末尾を削除すると、すべてが期待どおりに機能します。

私が誤って読んだのか、それとも間違って読んだのですか?

ベストアンサー1

FILE_CORE_NAME="$(/usr/bin/env basename $(/usr/bin/env awk -F "." '{print $1}' <<< "${FILE_TO_PROCESS}"))"; local FILE_CORE_NAME;

読みやすくするために数行で再フォーマットしても

FILE_CORE_NAME="$(
  /usr/bin/env basename $(
     /usr/bin/env awk -F "." '{print $1}' <<< "${FILE_TO_PROCESS}"
  )
)"
local FILE_CORE_NAME

多くのアカウントが間違っています。

  • awk{print $1}入力のすべての行でコマンドを実行するため、ファイルが$'/a.b/c\nd.e\nf/g.h.i'ある場合は出力されます/a<newline>d<newline>f/g'。改行文字はすべての文字で有効で、ファイル名はテキストにはできないため、行ベースのテキストユーティリティを使用して処理しないでください。 。
  • /foo.d/file.txt上記のように、単一行ファイルパスの場合でも、ファイルがある場合、または代わりにインポート/foo.bar.2020.jpgされます。基本名を先に完成し、最後まで検索したい部分です。/foo/foo.d/file/foo.bar.2020.
  • 2番目の部分では引用符が省略されるため、$(...)分割+グローブの影響を受けます。考えられる致命的な結果
  • --その後、オプションの区切り文字が見つからないため、basenameファイルパスが-
  • local関数のローカル変数を宣言するだけです。しかし、ここでは定義します。local 後ろにこれを変更して、関数呼び出し元の変数を変更します。その後、bash(組み込み機能を持つashとは反対local)では、変数はローカルで宣言されますが、locvar_inheritオプションが有効になっていない限り、値は設定されません。local var
  • すべての大文字の変数名は、環境変数名として保持するか、少なくともスクリプトと依存関係にわたってグローバルスコープを持つ変数名のままにしてください。
  • ここではそれを使用する点は見えません/usr/bin/env

ここでやるべきことは、zshに切り替えて次のことを行うことです。

local core_name=$FILE_TO_PROCESS:t:r

70年代のcshまたはvim(またはbashレコードの代替ですが、引数拡張ではありません)のように、:t尾名と:rルート名(拡張子が削除されます)を提供します。

を使用する必要がある場合は、bash次のことができます。

local core_name
core_name=$(basename -- "$FILE_TO_PROCESS") || return
core_name=${core_name%.*}

(これは、local組み込み機能を持つすべてのAshに似たシェルにも適用されます。)

末尾の改行を削除することを忘れないでください$(...)

たとえば、ifは空の$FILE_TO_PROCESS文字列になります/home/me/.zshrc。たとえば、関数の残りの部分でこの値で実行したい操作に応じて、この値だけでなく他の特別な値も$core_name保護できます-...$core_name

おすすめ記事