Я пишу функцию, которая выводит даты. Я хотел бы разрешить пользователю настраивать вывод, предоставляя аргументы с date
переменной окружения. Чтобы сохранить пробелы в строках формата, я хотел бы принимать аргументы в массиве следующим образом:
function argdates {
while [ $# -gt 0 ] && date "${DATE_ARGS[@]}" -d @$1
do shift
done
}
Пользователь может захотеть использовать массив, если в строке формата даты есть пробелы:
DATE_ARGS=( -u "+%y/%U, %I%p %a" )
argdates 1476395008 1493172224
# output:
# 16/41, 09PM Thu
# 17/17, 02AM Wed
Но в этом случае массив может оказаться излишним:
DATE_ARGS="-u -Iseconds"
argdates 1476395008 1493172224
# output:
# date: invalid option -- ' '
# Try 'date --help' for more information.
# output should be:
# 2016-10-13T21:43:28+00:00
# 2017-04-26T02:03:44+00:00
Я не хочу требовать массив для таких простых случаев. Можно ли узнать, какой тип переменной?
решение1
Мне кажется, что вы, возможно, захотите позволить своей функции передавать любые параметры командной строки непосредственно в GNU, date
при этом обрабатывая числовые непараметры особым образом:
argdates () {
local -a opts
local timestamp
while [ "$#" -gt 0 ] && [ "$1" != '--' ] && [[ "$1" != [0-9]* ]]; do
opts+=( "$1" )
shift
done
[ "$1" = '--' ] && shift
for timestamp do
date "${opts[@]}" -d "@$timestamp"
done
# or, with a single invocation of "date":
# printf '@%s\n' "$@" | date "${opts[@]}" -f -
}
Эта bash
функция будет проходить по аргументам командной строки и сохранять их в opts
массиве, пока не встретит аргумент, который является --
(стандартный способ обозначения конца опций) или который начинается с цифры. Каждый аргумент, сохраненный в , opts
смещается из списка аргументов командной строки.
После того, как найден аргумент, который не является опцией для date
, мы предполагаем, что остальные аргументы являются временными метками эпохи UNIX, и циклируем по ним, вызывая date
с нашими сохраненными опциями для каждой временной метки. Смотрите комментарий в коде, чтобы узнать, как сделать этот цикл более эффективным.
Примеры вызовов:
$ argdates 1476395008 1493172224
Thu Oct 13 23:43:28 CEST 2016
Wed Apr 26 04:03:44 CEST 2017
$ argdates -- 1476395008 1493172224
Thu Oct 13 23:43:28 CEST 2016
Wed Apr 26 04:03:44 CEST 2017
$ argdates +%D 1476395008 1493172224
10/13/16
04/26/17
$ argdates +%F 1476395008 1493172224
2016-10-13
2017-04-26
$ argdates -u 1476395008 1493172224
Thu Oct 13 21:43:28 UTC 2016
Wed Apr 26 02:03:44 UTC 2017
$ argdates -u -Iseconds 1476395008 1493172224
2016-10-13T21:43:28+00:00
2017-04-26T02:03:44+00:00
решение2
Это можно было бы сделать гораздо проще, отказавшись от использования массивов и предоставив пользователю возможность DATE_ARGS
просто указать строку, которую следует вставить в командную строку date
:
$ argdates(){
for d; do printf %s "$DATE_ARGS" | xargs date -d "@$d"; done
}
$ DATE_ARGS='-u "+%y/%U, %I%p %a"' argdates 1476395008 1493172224
16/41, 09PM Thu
17/17, 02AM Wed
$ DATE_ARGS='-u -Iseconds' argdates 1476395008 1493172224
2016-10-13T21:43:28+00:00
2017-04-26T02:03:44+00:00