Я не эксперт по mdadm, но, предполагая необработанные данные только со смещением, вы правы, поскольку вы можете изменить таблицу разделов для доступа к разделу как таковому. Вероятно, вам нужно удалить раздел, а затем создать новый раздел в нужном месте. MBR является автономным, никакие данные не будут записаны в сам раздел (, это верно только для первичных разделов ).
Альтернативно, вы можете обернуть блочное устройство петлевым устройством, начиная с заданного смещения. Сообщается, что смещение составляет 2048 секторов, что эквивалентно 2048 · 512 = 1048576 байт.
offset=1048576
losetup -f /dev/sdb3 -o $offset
Затем смонтируйте только что созданное блочное устройство контура (, обычно/dev/loop0
).
Или используя крепление напрямую:
mount -o loop,ro,offset=$offset /dev/sdb3 /mountpoint
(ro
добавлено по соображениям безопасности во время экспериментов.)
Нет возможности сделать это напрямую (, насколько я знаю ), но вы можете подделать это, добавив защитный символ новой строки, не являющийся -в подстановке команды, а затем удалив его впоследствии:
var=$(somecommand; echo x) # Add an "x" (and one newline that command
# substitution will remove) *after* the
# newline(s) we want to protect
var=${var%x} # Remove the "x" from the end
Обратите внимание, что статус выхода somecommand
теряется в процессе, так как и echo x
, и var=${var%x}
обычно устанавливают статус (на 0 ). Если вам нужно сохранить его до конца, вам нужно добавить немного жонглирования (с кредитом на Кусалананду):
var=$(somecommand; err=$?; echo x; exit "$err") # Make the subshell
# exit with somecommand's
# status
commandstatus=$? # Preserve the exit status of the subshell
var=${var%x}
# You can now test $commandstatus to see if the command succeeded
Обратите внимание, что обе переменные err
и commandstatus
хранят статус завершения команды, но они не являются избыточными, поскольку err
существует только в подоболочке, созданной $( )
, а commandstatus
существует только в родительская оболочка. Вы можете использовать одно и то же имя для обоих, но это может внести путаницу.
Кстати, если вам не нужно сохранять статус до тех пор, пока не будет обрезан "x", вы можете пропустить часть commandstatus
:
if var=$(somecommand; err=$?; echo x; exit "$err"); then
# somecommand succeeded; proceed with processing
var=${var%x}
dosomethingwith "$var"
else
echo "somecommand failed with exit status $?" >&2
fi
Единственными известными мне оболочками, в которых есть подстановка команд, которой можно запретить удаление завершающих символов новой строки, являютсяrc
(оболочка Unix V10 и plan9, а также общедоступный клон Байрона Ракитциса и его производные, такие как es
илиakanga
)и fish
.
Вrc
-подобно раковинам,
var = `{somecommand}
Сохраняет $ifs
слов с разделителями в выводе somecommand
в $var
переменных (, а переменные представляют собой массивы/списки вrc
).
С пустыми $ifs
, (ifs = ()
), которые сохраняют выходные данные как есть. Разделители также можно указать с помощью ``(separators){somecommand}
, поэтому:
var = ``(){somecommand}
Но rc
/ es
/ akanga
не очень похожи на Борна -.
Кроме того, обычно требуется удалить один символ новой строки.
Например, в:
dirname=$(dirname -- "$file")
Вы хотите удалить символ новой строки, добавленный dirname
, но не те, которые могут быть в конце каталога $file
.
rc
не имеет для этого встроенного оператора. Вам понадобится:
dirname = ``(){dirname -- $file | head -c -1}
(нет в стандартеhead
). В es
вы можете использовать оператор извлечения шаблона ~~
:
nl = '
'
dirname = <={ ~~ ``(){dirname -- $file} *$nl }
Что едва ли более разборчиво (, хотя может быть превращено в функцию ).
Подстановка команды оболочки fish
разбивает вывод на составляющие строки.
set var (somecommand)
Сохраняет строки вывода somecommand
в массив $var
(, а пустые строки сохраняются даже в конце вывода ).
Если вы установите $IFS
на пустой список или одну пустую строку, это разделение будет отключено, и из конца вывода (будет удалено до одного символа новой строки, по крайней мере, в текущих версиях fish
, IIRC за прошедшие годы на этом фронте произошло несколько изменений ). Итак,
begin; set -l IFS; set dir (dirname -- $file); end
является надежным.
Я не знаю ни одной оболочки, подобной Bourne -, которой можно было бы приказать не удалять все завершающие символы новой строки. Такое поведение требуется POSIX, и все оболочки, подобные Bourne -, делают это, даже если не в режиме posix (для тех, у кого есть такой, как bash или zsh ).
В bash
4.4+ вместо подстановки командвы также можете использовать readarray
в сочетании с заменой процесса (или конвейером с опцией lastpipe
и в не -интерактивных экземплярах):
readarray -td '' var < <(somecommand)
Здесь -d ''
означает разбиение на NUL. bash
все равно не поддерживает сохранение NUL в своих переменных, так что для замены подстановки команд этого будет достаточно.
readarray -t lines < <(somecommand)
Сохраняет эти строки вывода somecommand
в массив $lines
. Затем вы можете соединить их с новой строкой, чтобы восстановить этот вывод без одного конца новой строки:
IFS=$'\n'
output="${lines[*]}"
Но во всех этих подходах вы теряете статус выхода somecommand
.
Чтобы обойти эту неправильную функцию подстановки команд, удаляющую все символы новой строки, распространенной идиомой является добавление не -символа новой строки и удаление его (вместе с одним символ новой строки )впоследствии, как сказал Гордон.
Но чтобы сделать это без потери существующего статуса, вам нужно что-то вроде:
cmdsubst() { # args: var cmd args
eval "$1"'=$(shift; "$@"; ret=$?; printf.; exit "$ret")'
eval "$1=\${$1%.}; $1=\${$1%'
'}; return $?"
}
Это похоже на подстановку команд, за исключением того, что удаляется только до одного символа новой строки.
Используется как:
cmdsubst dir dirname -- "$file"
вместо:
dir=$(dirname -- "$file")
Или для более сложных команд:
cmdsubst var eval 'cmd1; for i in a b; do cmd "$i"; done'