Исправьте назначения массивов и измените тест на регулярное выражение.
#!/bin/bash
FNAME="JACK"
LNAME="BLACK"
SEARCHNAME=()
SEARCHNAME+=("JACK-BLACK")
SEARCHNAME+=("JOHN-JAMES")
SEARCHNAME+=("CHRIS-TOPHER")
SEARCHNAME+=("JEN-NAY")
NAME="${FNAME}-${LNAME}"
if [[ "${SEARCHNAME[@]}" =~ $NAME ]]; then
echo "PASSED"
else
echo "FAILED"
fi
echo "SEARCH IN: ${SEARCHNAME[@]}"
echo "FOR NAME: ${NAME}"
Я не могу точно воспроизвести «Неверный аргумент» для той эпохи в более старой системе, но:
# strace date -s '@-1'
…
clock_settime(CLOCK_REALTIME, {4294967295, 0}) = -1 EINVAL (Invalid argument)
settimeofday({4294967295, 0}, NULL) = -1 EINVAL (Invalid argument)
write(2, "date: ", 6date: ) = 6
write(2, "cannot set date", 15cannot set date) = 15
write(2, ": Invalid argument", 18: Invalid argument) = 18
write(2, "\n", 1
(А затем date
продолжает отображать дату, которую он хотел установить, хотя на самом деле он ее не установил.)
Проще говоря, date
вызывает ядро, чтобы установить дату на одну секунду раньше эпохи, и ядро сообщает ему, что предложенная дата недействительна.
Теперь в приведенной выше трассировке вы видите 4294967295 как количество секунд вместо -1. Это число равно 2^32 -1, и я запускал его на 32-битной -машине. Это на самом деле не источник проблемы :это проблема отображения в strace
, которая не знает, должно ли значение быть подписанным или нет. На самом деле количество секунд — это целое число со знаком типа time_t
. Glibc 2.23 в Linux определяет time_t
как __time_t
в /usr/include/time.h
, __time_t
как __TIME_T_TYPE
в/usr/include/bits/types.h
__TIME_T_TYPE
как __SYSCALL_SLONG_TYPE
, что равно __SQUAD_TYPE
в /usr/include/bits/typesizes.h
, и __SQUAD_TYPE
как 64 -тип битового знака в /usr/include/bits/types.h
. На стороне ядра, начиная с 4.4,определение типа аргумента вызова settimeofday
— это либо struct timespec
, где секунды — это __kernel_time_t
, который является 64-разрядным -битным типом со знаком на 64-битных -машинах, либоtime64_t
который является подписанным 64-битным -типом на 32-битных -машинах. Таким образом, ядро видит -1 как -1, а не какое-то большое положительное число.
Причина, по которой вы не можете вернуться в предыдущую эпоху, заключается в том, что ядро Linux явно отказывается это делать. Системный вызовsettimeofday
возвращает EINVAL («Недопустимый аргумент» ), еслиtimeval_valid
отклоняет заданную временную структуру, а эта функция отклоняет отрицательное число секунд.
В разных версиях ядра код организован по-разному, но я не думаю, что поведение изменилось.
Я не видел причин, по которым время, равное 0, было бы отклонено, и это работало на виртуальной машине, где я тестировал это.
Причина для проверки работоспособности, по-видимому, заключается в том, что существует код, который хранит время, прошедшее с начала эпохи, как целое число без знака, и, таким образом, не может справиться с датами, предшествующими эпохе. Некоторый код может интерпретировать 0 как «дата неизвестна», поэтому имеет смысл отклонить и 0, но на самом деле Linux этого не делает, и в любом случае это будет длиться всего секунду.
Времена, предшествующие эпохе, несомненно, могут быть представлены и ими можно манипулировать. Многим программам необходимо отслеживать время прошлых событий. База данных часовых поясов, которую использует практически каждая операционная система, содержит исторические данные, начиная с того времени, когда часовые пояса были кодифицированы (примерно в то время, когда железные дороги начали развиваться ). Но вы не можете сказать Linux-компьютеру, что текущее время до 1970 года.
Это может произойти, если представление об эпохе текущего часового пояса предшествует (UTC )эпохе Unix. Такие времена просто не могут быть представлены.