Создайте флаги для скрипта бэш-паролей

У меня возникла эта проблема, и я решил ее, перейдя в Системные настройки -> Рабочий стол -> снимите / отметьте опцию Показывать значки рабочего стола

Странная возможность сворачивать рабочий стол! Надеюсь, это вам поможет.

2
11.03.2018, 02:14
3 ответа

Así es como normalmente hago mis opciones, pero creo que terminará alargando su secuencia de comandos... Sin embargo, toma opciones en cualquier orden.

while (( $# )); do
    case $1 in
        -n)
            shift
            number=$1
        ;;
        -f)
            shift
            file_name=$1
        ;;
        -p)
            shift
            password=$1
            run=pass
        ;;
        -s)
            run=save
        ;;
        -u)
            shift
            username=$1
        ;;
        *)
            thing=$1
            save=what
        ;;
        shift
    esac
done
case $save in
    save)
        cat /dev/urandom \
            | tr -dc A-Za-z0-9.-@ \
            | head -c "$number" > "${DIR}/${file_name}.txt" && echo >> "${DIR}/${file_name}.txt"
        cat "${DIR}/${file_name}.txt"
    ;;
    pass)
        cat /dev/urandom \
        | tr -dc A-Za-z0-9.-@ \
        | head -c "$number" ; echo
    ;;
    *)
        cat /dev/urandom \
        | tr -dc A-Za-z0-9 \
        | head -c "$thing" ; echo
    ;;
esac

El bucle whilese ejecutará mientras haya opciones. shiftpasa a la siguiente opción, por lo que recorrerá cada uno de los argumentos que pase y los ejecutará a través de la declaración del caso para manejarlos correctamente.

0
27.01.2020, 22:03

La siguiente secuencia de comandos es más larga que la suya, pero toda la longitud adicional se debe a que agregué una función usagepara imprimir un mensaje de ayuda de uso (que también sirve para imprimir un mensaje de error cuando se detecta una condición de error )y agregó muchos comentarios para explicar qué hace el código y por qué.

El código que analiza las opciones y hace el trabajo es mucho más corto y simple, y más fácil de expandir (p. actualmente toma una opción -u usernamepero no hace nada con ella porque no mencionaste cómo debería usarse ). Se elimina todo el manejo especial de casos -, las "decisiones" sobre qué hacer y cómo hacerlo se toman en la declaración del caso y en algunas pruebas si/entonces inmediatamente posteriores.

También agregué una opción -dpara que pueda especificar un directorio de salida... pero eso es redundante como cualquier cosa excepto un ejemplo de cómo agregar otra opción, porque también agregué un código que verifica si el El archivo de salida contiene un carácter /, y solo antepone$outdir(renombrado desde su $DIR-. Es un buen hábito usar nombres de variables en minúsculas en su script, reservando mayúsculas para utilidades estándar )si no es así. es decir, puede usar -f /path/to/fileo -d /path/to -f file.

Por cierto, en lugar de crear un alias con la ruta completa a este script, recomiendo ponerlo en /usr/local/bino crear un directorio bin/sub -en su directorio de inicio y agregar ~/bina su $ SENDERO. Luego, puede escribir y guardar tantos scripts personalizados como desee allí.

#!/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

Por cierto, ya existen numerosos programas generadores de contraseñas -. p.ej. pwgen y makepasswd.

Solía ​​​​usar pwgenpara generar contraseñas de más de 16 dígitos hasta que escribí mi propio generador de frases de contraseña que selecciona aleatoriamente una cantidad de palabras de /usr/share/dict/wordsy las une con -generado aleatoriamente 1 -3 dígitos números y/o puntuación. /usr/share/dict/wordses todo -en minúsculas, por lo que mi secuencia de comandos pone aleatoriamente en mayúscula algunas de las letras. Esto genera contraseñas muy largas pero fáciles de recordar. Los dígitos aleatorios, la puntuación y las mayúsculas aumentan el espacio de búsqueda para el descifrado de fuerza bruta -y ayudan a garantizar que la seguridad de la contraseña no se vea comprometida por la previsibilidad del diccionario de palabras.

por ej.

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

La longitud de la contraseña es mucho más importante que la complejidad -cualquier contraseña de menos de 10 caracteres se puede descifrar en muy poco tiempo con -hardware moderno (un segundo o menos durante <= 7 caracteres, horas para 8 caracteres, unos meses para 10 caracteres ). Una contraseña de 55 caracteres es efectivamente indescifrable dentro de la vida útil del universo con la tecnología actual (, por lo que debería ser segura durante al menos 10 años ).

El problema es que cuanto más larga es una contraseña, más simple debe ser para que un humano pueda recordarla. Descubrí que solo necesito recordar el inicio de la contraseña y, al escribirla varias veces, asocio automáticamente (y, por lo tanto, recuerdo )los siguientes dígitos y palabras en la frase sin sentido.

3
27.01.2020, 22:03

Это вариант вашего скрипта:

#!/bin/bash

opt_l=8                 # password length is 8 by default
opt_o=/dev/stdout       # write to standard output by default
opt_s=0                 # insecure password by default
opt_u=                  # no default username

while getopts 'l:o:su:' opt; do
    case "$opt" in
        l) opt_l=$OPTARG ;;
        o) opt_o=$OPTARG ;;
        s) opt_s=1       ;;
        u) opt_u=$OPTARG ;;
        *) echo 'Error parsing options' >&2
           exit 1
   esac
done

args=( "$opt_l" 1 )

if (( opt_s )); then
    args=( -s "${args[@]}" )
fi

if [ -n "$opt_u" ]; then
    printf '%s: %s\n' "$opt_u" "$( pwgen "${args[@]}" )" >"$opt_o"
else
    pwgen "${args[@]}" >"$opt_o"
fi

Я изменил названия некоторых флагов, чтобы они больше соответствовали тому, что используют стандартные инструменты. Вместо того, чтобы печатать сообщение об ошибке при обнаружении неподдерживаемого флага, вы можете вывести пользователю некоторую информацию об использовании.

Главное здесь использование getopts. Он принимает спецификацию в виде строки параметров, которые вы используете. :в строке означает, что предыдущий символ опции принимает аргумент (другие опции являются логическими ).

В цикле while$optбудет опцией, а $OPTARGбудет аргументом опции, если флаг принимает аргумент.

Обычно также выполняется shift "$(( OPTIND - 1 ))"после цикла, но поскольку этот скрипт не принимает дополнительные операнды в командной строке, кроме опций и их аргументов, в этом нет необходимости. shiftгарантирует, что дополнительные операнды будут доступны как $1, $2и т. д.

Вы можете использовать скрипт как

$./script.sh -l 4         # generates password of length 4 in the terminal
$./script.sh -l 4 -o file # generates password of length 4 and saves to "file"
$./script.sh -u bob       # generates password of length 8, prepends with username "bob"
$./script.sh -s -u bob    # generates more random password of length 8, prepends with username "bob"

-s -u bobсовпадает с -ubob -sи -subob, а поскольку-u alice -s -u bob(более поздние параметры переопределяют более ранние ).

Было бы довольно легко удалить pwgenиз этого и просто использовать другой генератор паролей. Чтобы упростить это, можно поместить генератор паролей в отдельную функцию, что означает, что основной скрипт никогда не будет изменяться при замене генератора :

.
#!/bin/bash

passgen () {
    local args=( "$opt_l" 1 )

    if (( opt_s )); then
        args=( -s "${args[@]}" )
    fi

    pwgen "${args[@]}"
}

opt_l=8                 # password length is 8 by default
opt_o=/dev/stdout       # write to standard output by default
opt_s=0                 # insecure password by default
opt_u=                  # no default username

while getopts 'l:o:su:' opt; do
    case "$opt" in
        l) opt_l=$OPTARG ;;
        o) opt_o=$OPTARG ;;
        s) opt_s=1       ;;
        u) opt_u=$OPTARG ;;
        *) echo 'Error parsing options' >&2
           exit 1
   esac
done

if [ -n "$opt_u" ]; then
    printf '%s: %s\n' "$opt_u" "$( passgen )" >"$opt_o"
else
    passgen >"$opt_o"
fi

Например, это примерно ваш генератор:

passgen () {
    local source=/dev/urandom
    local chars='A-Za-z0-9'

    if (( opt_s )); then
        chars="$chars"'.-@'
    fi

    tr -dc "$chars" <"$source" | head -c "$opt_l"
}

... и следующее генерирует фразу-пароль, используя слова из/usr/share/dict/words(количество слов берется из опции -l). Если используется опция -s,он добавляет случайное число в конец вместо последнего слова.

passgen () {
    local dict=/usr/share/dict/words
    local numwords=$opt_l

    if (( opt_s )); then
        numwords=$(( numwords - 1 ))
    fi

    {
        shuf -n "$numwords" "$dict"

        if (( opt_s )); then
            printf '%d\n' "$RANDOM"
        fi
    } | tr '\n' ' ' | sed 's/ $//'
}

Работа с этой последней функцией passgen, команда

./script.sh -s -u bob -l 3

может генерировать что-то вроде

bob: cassis befluster 22625
0
27.01.2020, 22:03

Теги

Похожие вопросы