저는 Arch Linux와 systemd를 실행하고 있습니다.
나는 /etc/fstab
다음과 같은 것을 가지고 있습니다 :
LABEL=XYZ /mypath vfat noauto,[...]
/mypath/main /newplace none bind,noauto 0 0
/newplace
현재 설치하려면 두 가지 명령을 사용해야 합니다 .
mount /mypath
mount /newplace
나도 둘 umount
다 되어야 해요.
mount
이것을 하나의 (또는 umount
) 명령 으로 줄여야 합니다 .
mount /newplace
기존 스크립트로 인해 위에 표시된 정확한 mount
(및 관련) 명령을 사용해야 합니다. umount
밝히다:
단일 명령은 mount /newplace
먼저 마운트된 /mypath
다음 마운트 /newplace
되고 /mypath
마운트된 상태를 유지해야 합니다.
이 명령은 umount /newplace
먼저 마운트를 해제 /newplace
한 다음 마운트를 해제해야 합니다.반품제거 /mypath
.
/etc/fstab
내 장치의 다른 세부 정보를 변경할 수 있습니다 . 하지만 호출된 스크립트를 변경할 수는 없습니다 mount /newplace
. 또한 /newplace
스크립트가 실행되지 않는 한 일반적으로 마운트 해제된 상태를 유지해야 하기 때문에 자동 마운트할 수 없습니다 .
재귀 바인드 마운트, 공유, 개인, 슬레이브 및 기타 마운트 옵션에 대해 읽었지만 원하는 것을 달성할 방법을 찾지 못했습니다.
업데이트: 의견에 따르면 이는 분명히 재귀 마운트가 아니므로 "전제 조건" 마운트라고 부르겠습니다. 그 말이 맞기를 바랍니다. "역 재귀 설치"라는 용어를 생각했지만 좋지 않은 것 같습니다. 저는 '전제조건'을 먼저 이루어져야 하고, 필요한 조건에 대한 지속적인 기반을 제공하는 것이라고 생각합니다. 일반적으로 필수 조건을 계속 수행하는 동안 필수 조건을 잊어버리거나 삭제할 수 없습니다.
이 경우 /mypath
(예방)과 /newplace
(필수)는 모두 설치 시 설치된 상태로 유지되며 /newplace
호출 시 둘 다 제거됩니다(물론 반대 순서일 수도 있음) umount /newplace
.
이상적인 솔루션은 systemd, Python 3 또는 Xonsh를 사용하는 것입니다. (Bash 스크립트도 허용됩니다. zsh나 다른 쉘이 설치되어 있지 않습니다.)
답변1
구체적으로 전체 FS가 아닌 FS의 "home" 하위 디렉터리를 LABEL=XYZ
에 마운트하려는 경우 다음과 같은 줄을 추가할 수 있습니다./newplace
/mypath
LABEL=XYZ /newplace subdir subdir=main,srctype=vfat,noauto,... 0 0
그리고 다음과 같은 스크립트로 /sbin/mount.subdir
도우미( 직접 의미하지 않고 호출됨 )를 만듭니다.mount /newplace
#! /bin/zsh -p
(( EUID == 0 )) || exec sudo -- "$0" "$@"
PATH=/bin:/sbin:/usr/bin:/usr/sbin
# mount -t subdir -o subdir=foo -o otheroption source /dest calls us
# as mount.subdir source /dest -o rw,subdir=foo,otheroption
dev=${1?} dest=${2?} opts=( ${(s[,])4?} )
# extract mandatory subdir option
(( i = $opts[(I)subdir=*] )) || exit
subdir=${opts[i]#*=}
opts[i]=()
# extract optional srctype option
if (( i = $opts[(I)srctype=*] )); then
type=(-t "$opts[i]")
opts[i]=()
else
type=()
fi
tmpdir=$(mktemp -d) || exit
mounted()true
if
mount "$type[@]" -o "${(j[,])opts}" -- "$dev" "$tmpdir"
then
mount --bind -- "$tmpdir/$subdir" "$dest" || mounted()false
umount -- "$tmpdir"
fi && rmdir -- "$tmpdir" && mounted
전체 FS를 tmpdir에 마운트하고 하위 디렉터리를 대상 위치에 바인드 마운트한 다음 tmpdir을 마운트 해제하고 삭제합니다.
이후 편집에서 명확히 설명한 것처럼 실제로 마운트하고 싶고 /newplace
하위 디렉터리에 FS를 마운트하려는 최종 목표를 향한 중간 단계가 아닌 유사한 접근 방식을 취할 수 있으며 이는 더 쉬워집니다. 필요한 파일 시스템을 마운트하는 도우미 프로그램:/mypath
/mypath
/myplace
LABEL=XYZ /mypath vfat noauto,[...]
/myplace/main /newplace prereq prereq=/myplace,noauto,... 0 0
/sbin/mount.prereq
다음과 같은 스크립트로 도우미를 만듭니다 .
#! /bin/zsh -p
(( EUID == 0 )) || exec sudo -- "$0" "$@"
PATH=/bin:/sbin:/usr/bin:/usr/sbin
src=${1?} dst=${2?} opts=( ${(s[,])4?} )
# extract prereq options
for prereq in ${(M)opts:#prereq=*}; do
prereq=${prereq#*=}
mountpoint -q -- $prereq ||
mount -- $prereq ||
exit
done
opts=(${opts:#prereq=*})
exec mount --bind -o "${(j[,])opts}" -- "$src" "$dst"
를 제거한 /mypath
후에는 자동으로 제거되지 않습니다 ./newplace
POSIX 쉘과 동일한 구문(그래서 에서도 작동해야 함 bash
)은 다음과 같습니다.
#! /bin/sh -
[ "$(id -u)" -eq 0 ] || exec sudo -- "$0" "$@"
PATH=/bin:/sbin:/usr/bin:/usr/sbin
src="${1?}" dst="${2?}"
set -o noglob
IFS=,
set -- ${4?}
# extract prereq options
for opt do
case $opt in
(prereq=*)
prereq=${opt#*=}
mountpoint -q -- "$prereq" ||
mount -- "$prereq" ||
exit
;;
(*)
set -- "$@" "$opt"
esac
shift
done
opts="$*"
exec mount --bind -o "$opts" -- "$src" "$dst"
(검증되지 않은).
당신이 할 수 없다면편집하다스크립트를 계측할 수 있습니다. 예를 들어, 다음과 같이 작성되면 다음 bash
과 같이 호출됩니다.
bash -c '
mount() {
if [[ $1 = "/newplace" ]]; then
command mount /mypath || return
fi
command mount "$@"
}
export -f mount
exec "$0" "$@"' your-script its args
또는 에 작성된 경우 zsh
다음을 추가 ~/.zshenv
(또는 해당 스크립트에 대해 설정 /some/dir/.zshenv
)합니다.ZDOTDIR=/some/dir
if [[ $ZSH_SCRIPT:P = /path/to/your-script ]]; then
mount() {
if [[ $1 = /newplace ]]; then
command mount /mypath || return
fi
command mount "$@"
}
fi
또는 모든 쉘에 대해 동일한 작업을 수행하는 스크립트를 추가하십시오 mount
./some/dir
#! /bin/sh -
if [ "$1" = /newplace ]; then
/bin/mount /mypath || exit
fi
exec /bin/mount "$@"
스크립트를 호출합니다.
PATH="/some/dir:$PATH" your-script its args