ファイル名評価、悪?

ファイル名評価、悪?

プロジェクトを生成するための次のスクリプトがあります。

clear
version="0.0.2"
echo "Project creator"
echo "---------------"
# ask user to specify a directory (could start with spelled-out home directory)
directoryName=""
# Input must meet the following criteria: 
# 1.) No spaces at all in the directory path
# 2.) some characters must be entered
while [[ ${#directoryName} -eq 0 || $directoryName == *" "* ]]
        do
                echo -e "\nEnter the full directory of the project (no spaces):"
                read directoryName
        done
echo "You entered: $directoryName"
# uate directoryName so that the rest of the code can understand it
# create directory if it does not exist
eval mkdir "$directoryName"
# if successful
if [ $? -eq 0 ]
then
        # call executable in /home/miwarren/CPPFileCreator to create a main.cpp file to put in the folder
        $HOME/CPPFileCreator/a.out $directoryName
        # copy a run.sh file into the folder, too...
        eval cp $HOME/CPPFileCreator/run.sh $directoryName/run.sh
        # you might want to put a fileCreator.sh in the folder as well
        eval cp $HOME/fileCreator.sh $directoryName/fileCreator.sh
fi

すべての空白を削除しました(挿入攻撃のために安全でない各文字列に少なくとも1つの空白があるとします)。変数が存在する場合は、ユーザーがパス部分($HOMEホームディレクトリなど)を綴る必要はありません。

ここで引き続き使用できますかeval?そうでない場合はどうすればよいですか?

ベストアンサー1

「変数が存在するときにユーザーがパス部分を綴る必要はありません(たとえば、ホームディレクトリの場合は$ HOME)。」

これは次のことなく実行できますeval

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

これにはいくつかの制限があります。まず、HOMESとHOMEの両方が置換先の変数名である場合は、誤ったマッチングを防ぐためにHOMESを置き換える必要があります。今後家。

エクスポートしたすべての変数に代替を適用する

バッシュ使用:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

たとえば、

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

このアプローチは変数名を長さで並べ替えないため、上記の変数重複の問題が発生します。

変数名を長さで並べ替えることでこの問題を解決できます。

while IFS== read -r n name val
do
   s="${s//\$$name/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

ユーザーが変数名を入力した場合いいえ存在しますが、初期文字が短い名前と一致する場合は、短い名前が置き換えられます。これが重要な場合は、次のコードを使用して、この変数に中括弧表記を使用するようにユーザーに要求することで、これを回避できます。

while IFS== read -r n name val
do
   s="${s//\$\{$name\}/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

たとえば、

$ s='${HOME}/${A}/${B}'
$ while IFS== read -r n name val; do s="${s//\$\{$name\}/$val}"; done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)
$ echo "$s"
/home/john1024/alpha/beta

おすすめ記事