Линукс Торвальдс предлагает noatime
.
Определения noatime
иnodiratime
:
- noatime : Without the "noatime" flag on your file system every read will cause a write, because the file system will update the access time. This is bad for the life-time of your SSD, since it supports a limited number of writes and this is causing significantly more writes.
Linux kernel developer Ingo Molnár claimed that it (atime) was “perhaps the most stupid Unix design idea of all times.” To disable the tracking of atime, the noatime option can be used to mount filesystems. For IO intensive tasks, the performance reward for turning off atime can be immediately apparent. But, turning off atime unconditionally will occasionally break certain software like mail tools that compare mtime and atime to determine whether there is unread mail or not. The tmpwatch utility and some backup tools also use atime and can misbehave if atime is incorrect. Audit requirements are another reason for keeping atime enabled.
- nodiratime : This is the same as the noatime option but this only applies to directories. Note that turning on noatime implicitly means that nodiratime is enabled as well.
Ошибка, которую вы получаете, указывает, что $chunk
содержит многострочное значение, все числа от 0 до 9. Это произойдет, если слово -расщепление не произойдет в результате $(seq...)
в for
.
Обычный способ предотвратить разбиение слова -заключается в заключении расширения в двойные -кавычки, чтобы for chunk in "$(seq...)"
не расширялось. Но здесь это не так, поскольку вы бы знали, добавили ли вы двойные -кавычки, и в любом случае это работает в некоторых случаях.
Но разбиение слова -не всегда одинаково, оно основано на значении IFS
, которое по умолчанию содержит пробел, табуляцию и новую строку($' \t\n'
с использованием стиля C -цитирования ). Если он содержит что-то другое, то эти символы будут приняты в качестве разделителей слов.
И действительно, вы модифицировали IFS
внутри select
, непосредственно перед вызовомfoo
:
local IFS=@
case "@${options[*]}@" in
(*"@$opt@"*)
foo
Способ работы области видимости переменных в Bash заключается в том, что foo
также видит измененное значение IFS
. local
не означает, что изменение видно только этой функции,но вместо этого он также виден для всех подфункций, вызываемых с этого уровня:
$ x=999
$ a() { echo "a: x=$x"; }
$ b() { local x=$1; a; }
$ b 123
a: x=123
Это не похоже на то, что было бы, скажем, в C.
В качестве обходного пути можно было бы вместо этого сохранить IFS
в другую переменную, что-то вроде этого:
local oldifs=$IFS
IFS=@
str="@${options[*]}@"
IFS=$oldifs
case $str in...
или изменить его в подоболочке (, скрывая IFS
изменение там):
str=$(IFS=@; echo "@${options[*]}@")
case $str in...
Вы также можете создать функцию для объединения строк (, скрывающую IFS
изменение в функции ), вам просто нужны ссылки на имена для передачи переменных по имени:
# join a b c:
# join the values of array 'a' with the character 'b', and put the result in 'c'
join() {
local -n _arr=$1
local IFS=$2
local -n _res=$3
_res="${_arr[*]}"
}
src=(11 22 33)
join src @ dst
echo "$dst" # outputs "11@22@33"
(Конечно, это немного громоздко для одного использования, и ссылки на имена тоже не идеальны :ссылка на имя внутри функция не может ссылаться на переменную с таким же именем снаружи это (по крайней мере в Bash 4 ). Небольшое преимущество этого по сравнению с просто использованием подстановки команд заключается в том, чтобы избежать форка для запуска подоболочки.)
Или, на всякий случай, (повторно )устанавливайте IFS
каждый раз, когда вам это нужно. Внутриfoo
:
foo() {
local IFS=$' \t\n' # or just IFS=$'\n'
for chunk in $(seq...); do
...
}