проблема с интерпретацией псевдонима в аргументах команды

Ядро не обрабатывает монтирование привязки, отличное от нормального монтирования после факт. Единственное отличие состоит в том, что происходит во время работы mount .

Когда вы монтируете файловую систему (например, с помощью mount -t ext4 / dev / sda1 / mnt ), ядро ​​(немного упрощенное) выполняет три шага:

  1. Ядро ищет драйвер файловой системы для указанного типа файловой системы (если вы опустите -t или используете -t auto mount угадывает тип за вас и предоставляет предполагаемый тип ядру)
  2. Ядро указывает драйверу файловой системы получить доступ к файловой системе, используя путь к исходному тексту и любые предоставленные параметры. На данный момент файловая система идентифицируется только парой старший: младший номер.
  3. Файловая система привязана к пути (точке монтирования). Ядро также использует здесь некоторые параметры монтирования. ( nodev , например, опция в точке монтирования, а не в файловой системе. У вас может быть монтирование с привязкой с nodev и без него)

Если вы выполняете монтирование с привязкой ( например, с mount --bind / a / b ) происходит следующее:

  1. Ядро решает, какая файловая система содержит исходный путь и относительный путь от точки монтирования до каталога.
  2. Файловая система привязана к новой точке монтирования с использованием параметров и относительного пути.

(Я пропущу mount --move , потому что это не имеет отношения к вопросу.)

Это очень похоже на то, как файлы создаются в Linux:

  1. Ядро решает, какая файловая система отвечает за каталог, в котором должен быть создан файл.
  2. Создается новый файл в файловой системе. На данный момент у файла есть только номер inode.
  3. Новый файл связан с именем файла в каталоге.

Если вы сделаете жесткую ссылку, произойдет следующее:

  1. Ядро разрешит номер inode исходного файла.
  2. Файл связан с целевым именем файла.

Как видите, созданный файл и жесткая ссылка неотличимы:

$ touch first
$ ln first second
$ ls -li
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/first
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/second

Но , поскольку вы можете идентифицировать все жесткие ссылки на файл, сравнивая номера inode, вы можете идентифицировать все подключения к файловой системе с помощью сравнивая старшее: младшее количество маунтов.

Вы можете сделать это с помощью findmnt -o TARGET, MAJ: MIN или напрямую посмотрев на / proc / self / mountinfo ( подробнее см. В документации ядра Linux информация ).

Следующий скрипт Python перечисляет все привязки. Предполагается, что самая старая точка монтирования с кратчайшим относительным путем к корню смонтированной файловой системы является исходной точкой монтирования.

#!/usr/bin/python3

import os.path, re
from collections import namedtuple

MountInfo = namedtuple('MountInfo', ['mountid', 'parentid', 'devid', 'root', 'mountpoint', 'mountoptions', 'extra', 'fstype', 'source', 'fsoptions'])

mounts = {}

def unescape(string):
    return re.sub(r'\\([0-7]{3})', (lambda m: chr(int(m.group(1), 8))), string)

with open('/proc/self/mountinfo', 'r') as f:
    for line in f:
        # Parse line
        mid, pid, devid, root, mp, mopt, *tail = line.rstrip().split(' ')
        extra = []
        for item in tail:
            if item != '-':
                extra.append(item)
            else:
                break
        fstype, src, fsopt = tail[len(extra)+1:]
        # Save mount info
        mount = MountInfo(int(mid), int(pid), devid, unescape(root), unescape(mp), mopt, extra, fstype, unescape(src), fsopt)
        mounts.setdefault(devid, []).append(mount)

for devid, mnts in mounts.items():
    # Skip single mounts
    if len(mnts) <= 1:
        continue
    # Sort list to get the first mount of the device's root dir (if still mounted)
    mnts.sort(key=lambda x: x.root)
    src, *binds = mnts
    # Print bind mounts
    for bindmount in binds:
        if src.root == bindmount.root:
            srcstring = src.mountpoint
        else:
            srcstring = src.mountpoint+':/'+os.path.relpath(bindmount.root, src.root)
        print('{0} -> {1.mountpoint} ({1.mountoptions})'.format(srcstring, bindmount))

7
31.08.2017, 12:03
1 ответ

Поскольку gitявляется псевдонимом , оканчивающимся пробелом, bash выполняет раскрытие псевдонима для слова сразу после него:

$ alias mv='mv -i'
$ alias git=': git '
$ set -x
$ git mv
+ : git mv -i

Из документов:

Если последний символ значения псевдонима является пробелом, то следующий Командное слово, следующее за псевдонимом, также проверяется на расширение псевдонима.

Сделайте gitпсевдонимом без пробела:

alias git='LANG=en_US git'

Обратите внимание, что:

Первое слово замещающего текста проверяется на псевдонимы, но слово, идентичное раскрываемому псевдониму, не раскрывается второй раз. Это означает, что можно использовать псевдоним lsдля ls -F, для instance, и Bash не пытается рекурсивно расширять замену текст.

Итак, вам не нужно \git.

15
27.01.2020, 20:15

Теги

Похожие вопросы