No Ubuntu, montei um arquivo .img de disco bruto como um dispositivo de loop que contém um LVM criptografado por LUKS com uma instalação do Ubuntu nele.
É montado assim: (a saída é delsblk -o NAME,PKNAME,KNAME,FSTYPE,SIZE /dev/loop0
NAME PKNAME KNAME FSTYPE SIZE
loop0 loop0 240G
├─loop0p1 loop0 dm-11 ext4 487M
├─loop0p2 loop0 dm-12 1K
└─loop0p5 loop0 dm-13 crypto_LUKS 239.5G
└─cloneluks dm-13 dm-14 LVM2_member 239.5G
├─ubuntuclone-lv_swap dm-14 dm-15 8G
└─ubuntuclone-lv_root dm-14 dm-16 ext4 231.5G
Existe algum comando que eu possa usar em um script para retornar o "dispositivo de bloco" raiz (não tenho certeza se esse é o termo correto) quando eu dou o nome do LV montado?
Eu esperava que isso lsblk -no pkname /dev/ubuntuclone/lv_root
funcionasse, mas não gera nada - usar kname
me dá dm-16
.
Eu quero chegar a loop0
.
Também vi esta resposta que sugeria que eu poderia usar "$(basename "$(readlink -f /dev/VG/LV)")"
, mas não consegui descobrir como usá-la:
dev=/dev/ubuntuclone/lv_root ; echo "$(basename "$(readlink -f $dev)")"
saídas dm-16
.
Não consigo descobrir como "passar" pelo contêiner crypto_LUKS.
É isso que estou procurando:
para entrada:
/dev/ubuntuclone/lv_root
ouubuntuclone-lv_root
Gostaria de obter a saída:
/dev/loop0
Obrigado.
editar: Acho que usar lsblk --json | jq
pode ser exatamente o que eu quero, mas estou tendo muita dificuldade em descobrir os encantamentos corretos para jq
...
Você pode usar
--inverse
para obter as dependências em ordem reversa para um dispositivo:Com isso, você pode adicionar
--list
para achatar a estrutura em "árvore" e usar apenastail -1
para imprimir a última linha. Então, no seu caso, o comando completo ficaria assim:Minha opinião "profissional" é que jq é um exagero para essa tarefa e o pipeline simples na resposta do Vojtech Trefny é a melhor opção, a menos que você tenha algum fator extra que o incentive a usar JSON. Mas já que você perguntou, aqui está uma maneira de fazer isso:
(quebras de linha no programa jq são apenas para legibilidade e podem ser omitidas)
A estratégia aqui é basicamente:
($path | ltrimstr("/dev/") | gsub("/"; "-")) as $name
: Transforme o caminho de entrada, de--arg path <path>
, em um nome de dispositivo de bloco removendo o/dev/
prefixo e substituindo tudo/
por-
(como bônus, você pode passar o nome do dispositivo de bloco em vez de um caminho e esta parte será uma operação sem efeito, então ainda deve funcionar).blockdevices[]
: Dividir a matriz de nível superiorblockdevices
em elementos individuais para processamento posteriorselect(any(.. | objects | select(.name == $name)))
:Entre esses elementos, selecione apenas aquele (teoricamente deve haver apenas um, mas se houver vários, o programa emitirá todos) que, em algum lugar em sua hierarquia, contém um objeto JSON com umname
campo cujo valor corresponde$name
ao da etapa 1"/dev/\(.name | gsub("-"; "/"))"
: Extraia oname
campo no nível superior de cada elemento selecionado e converta o nome do dispositivo de volta para um caminho. Observe que isso pressupõe que qualquer elemento-
presente no bloco "nome do dispositivo" deva ser convertido novamente para "a"/
para obter o caminho, o que é trivialmente verdadeiro no seu exemplo (não há-
"s" no nomeloop0
), mas se você encontrar uma situação em que isso não seja verdade, terá que adaptar a lógica de acordo.É possível que isso pudesse ser um pouco mais eficiente ou pelo menos mais curto; não pensei em otimizá-lo depois que encontrei algo que funcionasse.