Это работает на Вас?
date -d "-1 month -$(($(date +%d)-1)) days" "+%a %b %d 00:00:00 %Z %Y"
date -d "-$(date +%d) days -0 month" "+%a %b %d 23:59:59 %Z %Y"
Проблема заключается в тех случаях, когда содержимое $ x
не было очищено и содержит данные, которые потенциально могут находиться под контролем злоумышленника в случаях, когда код оболочки может в конечном итоге использоваться с привилегиями контекст эскалации (например, сценарий, вызываемый приложением setuid, сценарий sudoers или используемый для обработки данных вне сети (CGI, DHCP-перехватчик ...) прямо или косвенно).
Если:
x='(PATH=2)'
То:
x=$((1-$x)))
имеет побочный эффект установки ПУТЬ
на 2
(относительный путь, который вполне может быть под контролем злоумышленника). Вы можете заменить PATH
на LD_LIBRARY_PATH
или IFS
... То же самое происходит с x = $ ((1-x))
в bash, zsh или ksh (не тире и не yash, которые принимают только числовые константы в переменных).
Обратите внимание, что:
x=$((1-$x))
не будет работать должным образом для отрицательных значений $ x
в некоторых оболочках, которые реализуют (необязательный согласно POSIX) оператор -
(декремент) (как и в случае x = -1
, это означает, что оболочка должна вычислить арифметическое выражение 1–1
). «$ ((1-x))»
не имеет проблемы, поскольку x
раскрывается как часть (не раньше) арифметической оценки.
В bash
, zsh
и ksh
(не тире
или yash
), если x
:
x='a[0$(uname>&2)]'
Тогда расширение $ ((1- $ x))
или $ ((1-x))
приводит к тому, что uname
, которая должна быть выполнена (для zsh
, a
должен быть переменной массива, но, например, для этого можно использовать psvar
).
Таким образом, не следует использовать неинициализированные или незащищенные внешние данные в арифметических выражениях в оболочках (обратите внимание, что арифметические вычисления могут быть выполнены с помощью $ ((...))
(также известного как ] $ [...]
в bash
или zsh
), но также в зависимости от оболочки в let
, [
/ test
, declare / typeset / export ...
, return
, break
, continue
, ] exit
, printf
, print
встроенные функции, индексы массивов, ((..))
и [[...]]
и многие другие).
Чтобы проверить, что переменная содержит буквальное десятичное целое число, вы можете использовать POSIXly:
case $var in
("" | - | *[!0123456789-]* | ?*-*) echo >&2 not a valid number; exit 1;;
esac
Помните, что [0-9]
в некоторых регионах соответствует более чем 0123456789. [[: digit:]]
должно быть в порядке, но я бы не стал на это делать ставку.
Также помните, что числа с ведущими нулями в некоторых контекстах рассматриваются как восьмеричные ( 010
иногда равно 10, иногда 8), и имейте в виду, что приведенная выше проверка позволит пропускать числа, которые потенциально больше максимального целого поддерживается вашей системой (или любым другим приложением, в котором вы будете использовать это целое число; например, bash обрабатывает 18446744073709551616 как 0 как 2 64 ). Таким образом, вы можете добавить дополнительные проверки в этот оператор case выше, например:
(0?* | -0?*)
echo >&2 'Only decimal numbers without leading 0 accepted'; exit 1;;
(-??????????* | [!-]?????????*)
echo >&2 'Only numbers from -999999999 to 999999999 supported'; exit 1;;
Примеры:
$ export 'x=psvar[0$(uname>&2)]'
$ ksh93 -c 'echo "$((x))"'
Linux
ksh93: psvar: parameter not set
$ ksh93 -c '[ x -lt 2 ]'
Linux
ksh93: [: psvar: parameter not set
$ bash -c 'echo "$((x))"'
Linux
0
$ bash -c '[[ $x -lt 2 ]]'
Linux
$ bash -c 'typeset -i a; export a="$x"'
Linux
$ bash -c 'typeset -a a=([x]=1)'
Linux
$ bash -c '[ -v "$x" ]'
Linux
$ mksh -c '[[ $x -lt 2 ]]'
Linux
$ zsh -c 'echo "$((x))"'
Linux
0
$ zsh -c 'printf %d $x'
Linux
0
$ zsh -c 'integer x'
Linux
$ zsh -c 'exit $x'
Linux
Дополнительная информация по адресу:
x [0 $ (...)]
). bash
.