Когда вы говорите :read var <file
, дескриптор файла -закрывается после завершения команды. Следовательно, в следующий раз в цикле дескриптор файла -сбрасывается в начало.
В случае exec 3<file
, когда вы говорите read -r -u 3 var
, дескриптор файла остается открытым, даже когда команда чтения завершается, И позиция чтения обновляется, поэтому в следующий раз чтение захватит следующую строку.
Примечание. :Даже если вы сделали exec 0<file
, а затем read -r var
, он все равно будет вести себя одинаково.
Поместите эти функции в свой.bashrc
:
parent() {
local count
local arg
count=$(($1+1))
if [ "$2" = "" ]
then
arg="$PWD"
else
arg="$2"
if [[ $arg != /* ]]
then
printf 'Warning: "%s" does not begin with "/".\n' "$arg"
fi
fi
cut -d/ -f1-"$count" <<< "$arg"
}
tparent() { # The ‘t’ stands for “tilde”.
local count
local arg
local home
count=$(($1+1))
if [ "$2" = "" ]
then
arg="$PWD"
else
arg="$2"
fi
if [ "$3" = "" ]
then
home="$HOME"
else
home="$3"
fi
if [[ $home != /* ]]
then
printf 'Warning: "%s" does not begin with "/".\n' "$home"
fi
if [[ $arg/ != $home/* ]]
then
printf 'Error: "%s" does not begin with "%s".\n' "$arg" "$home"
return 1
fi
printf '%s' "~${arg/$home}" | cut -d/ -f1-"$count"
}
Используется cut -d/ -f1-number
для извлечения первыхN
компонентов имени пути.number
должно бытьN
+1 потому что нулевая строка перед первым /
считается первым полем.
Использование:
$ pwd
/home/gman/stack/JW
$ parent 3
/home/gman/stack
$ tparent 1
~/stack
Это может обрабатывать пути с пробелами и символами табуляции, но не символы новой строки.