Bashパスワードスクリプト用のフラグの生成

Bashパスワードスクリプト用のフラグの生成

ランダムパスワードを生成し(「フラグ」が正しい場合)、それをtxtファイルに保存するbashスクリプトを作成しました。単一のコマンドで実行できるように、スクリプトパスにエイリアスを追加しました。私はそれを「ランド」と呼びます。

私がすでに持っているのはうまくいきますが、まったくエレガントではありません。まず、フラグが今のように固定されているよりもどんな順序でも含めることができたらと思います。現在は2つだけ持っています。 -pは「セキュリティパスワード」を意味し、-sは「保存」を意味します。 "username"を表すために1つ以上の-uを追加したいのですが、現在のコード状態が気に入らないので、今は保留しています。

次のようにコマンドを実行したいと思います。

rand -FLAGS_IN_ANY_ORDER -NUMBER -FILE_NAME

以下はコードの現在のバージョンです。

#!/bin/bash

num=$#
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

if [[ "$1" = "-p" ]]; then
    cat /dev/urandom \
    | tr -dc A-Za-z0-9.-@ \
    | head -c $2 ; echo

elif [[ "$1" = "-ps" ]] && [[ "$3" = * ]]; then
    cat /dev/urandom \
    | tr -dc A-Za-z0-9.-@ \
    | head -c $2 > $DIR/$3.txt && echo >> $DIR/$3.txt

    cat $DIR/$3.txt

elif [[ "$1" = "-s" ]] && [[ "$3" = * ]]; then
    cat /dev/urandom \
    | tr -dc A-Za-z0-9 \
    | head -c $2 > $DIR/$3.txt && echo >> $DIR/$3.txt

    cat $DIR/$3.txt

else
    cat /dev/urandom \
    | tr -dc A-Za-z0-9 \
    | head -c $1 ; echo
fi

理想的には、可能な限り少ないコード行を望んでいますが、ifすべてのステートメントはそうではありません。

getopts私はこれを試しましたが、case単に動作させることはできません。これは私が今まで持っているコードの中で壊れていない唯一のバージョンです。

しかし、弁護すると、私はUNIX系システムが初めてで、数週間前からbashスクリプトの作成を始めました。

この問題をどのように解決しますか?

ベストアンサー1

次のスクリプトはあなたよりも長いですが、usageそれを使用してヘルプメッセージを印刷する機能を追加し(エラー状態が検出された場合にエラーメッセージを印刷するためにも使用されます)、説明のために多くのコメントを追加したため、すべての追加の長さが発生しますしました。どのようなコードを実行し、その理由は何ですか?

オプションを解析して操作を実行するコードは、はるかに短く、単純で拡張が簡単です(たとえば、現在のオプションを使用していますが、-u username使用方法について言及していないため、そのオプションでは何もしません)。すべての特別なケースでは処理が削除され、実行するアクションと実行方法の「決定」は、if / thenテストが続くCaseステートメントで行われます。

出力ディレクトリを指定できるようにオプションも追加しました...しかし、出力ファイルに文字が-d含まれていることを確認するコードも追加したため、他のオプションを追加する方法の例外は重複します。/前に追加するだけです$outdir(名前から名前を変更します。スクリプトでは変数名を小文字として使用し、標準ユーティリティでは大文字を保持することをお勧めします)。つまり、またはを$DIR使用できます。-f /path/to/file-d /path/to -f file

ただし、このスクリプトへのフルパスを含むエイリアスを作成しないでください。これをホームディレクトリに入れるか、サブディレクトリを作成して/usr/local/bin$ PATHに追加することをお勧めします。その後、そこから必要な数のカスタムスクリプトを作成して保存できます。bin/~/bin

#!/bin/bash

usage() {
  # this function prints a usage summary, optionally printing an error message
  local ec=0

  if [ $# -ge 2 ] ; then
    # if printing an error message, the first arg is the exit code, and
    # all remaining args are the message.
    ec="$1" ; shift
    printf "%s\n\n" "$*" >&2
  fi

  cat <<EOF
Usage:
       $(basename $0) [-p | -s file | -u <user> | -d <dir> ] <[-l] length>

Generates a random password of specified length, containing only
alpha-numeric characters.

Required arguments:

  -l <length>     Length of password.  Just the length without '-l' also works.

Options:

  -p              Allow some punctuation characters in password.
  -s <file>       Save output to filename.
  -d <dir>        Output directory for the save file
  -u <user>       Username.  At present this does nothing.

  -h              This help message.
EOF

  exit $ec
}

# Initialise variables
length=''
file=''
username=''
pattern='A-Za-z0-9'
outdir=$(dirname "$0")

# -s, -l, -u and -d require an arg. -h and -p don't. The leading ':' in
# the getopts string enables 'silent' error mode (i.e. we handle
# any errors ourselves)
while getopts ':hps:l:u:d:' opt; do
  case "$opt" in 
    p) pattern='A-Za-z0-9.-@' ;;
    s) file="$OPTARG" ;;
    l) length="$OPTARG" ;;
    u) username="$OPTARG" ;;
    d) outdir="$OPTARG" ;;

    h) usage ;;
    :) usage 1 "-$OPTARG requires an argument" ;;
    ?) usage 1 "Unknown option '$opt'" ;;
  esac
done

shift $((OPTIND -1))

# Length can be specified as either `-l nnn` or just `nnn` on the cmd line
# this code exits with an error message if no length is specified.
#
# It would probably be better to give length a default value instead.
# Just change `length=''` under the Initialise variables comment above
# to whatever you want as the default, and then delete the '[ -z "$1" ]'
# line below. Remember to update the usage message - documentation should
# always match what the code does.
if [ -z "$length" ] ; then
  [ -z "$1" ] && usage 1 "Length option is required"
  length="$1"
  shift
fi

# if there are any remaining args on the line, we don't know what to do
# with them, so exit with an error message.
[ -n "$*" ] && usage 1 "Unknown arguments: '$*'"

password=$(cat /dev/urandom | tr -dc "$pattern" | head -c "$length")

# I don't know why you want an extra newline in the output, but do it anyway.
printf "$password\n\n"

if [ -n "$file" ] ; then
   # if $file doesn't have a /, pre-pend "$outdir"
   [[ $file =~ '/' ]] || file="$outdir/$file"
   printf "$password\n\n" > "$file" 
fi

ところで、すでに多くのパスワード生成プログラムが存在します。例えば普遍的な根そしてmakepasswd

私はいくつかの単語をランダムに選択し、それをランダムに生成された1〜3桁の数字および/または句読点に関連付ける独自のパスワードジェネレータを作成 pwgenするまで、16桁以上のパスワードを生成しました。すべて小文字なので、私のスクリプトはいくつかの文字をランダムに大文字で表示します。その結果、長いが覚えやすいパスワードが生成されます。ランダムな数字、句読点、および大文字は、無差別代入攻撃の検索スペースを増やし、単語辞書の予測可能性によってパスワードの強度が損なわれないようにするのに役立ちます。/usr/share/dict/words/usr/share/dict/words

例えば

$ random-password.sh 
31 surVeying % deRAngement 6 ratiocinations 51 sunDowns
$ printf '%s' '31 surVeying % deRAngement 6 ratiocinations 51 sunDowns' | wc -c
55

パスワードの長さは複雑さよりはるかに重要です。長さが10文字未満のパスワードは、最新のハードウェアを使用すると非常に短い時間で復号化できます(<= 7文字は1秒以下、8文字は数時間、10文字は数ヶ月かかります)。 )文字)。現在の技術では、55文字のパスワードは宇宙の存在中に事実上解読できません(したがって、少なくとも10年間は​​安全でなければなりません)。

問題は、パスワードが長いほど、人々はパスワードを覚えやすくする必要があるということです。私はパスワードの始まりを覚えておくだけで、パスワードを数回入力すると、意味のないフレーズの次の数字と単語が自動的に連結(したがって記憶)されることがわかりました。

おすすめ記事