私はArch Linuxとsystemdを実行しています。
私は/etc/fstab
次のようなものがあります:
LABEL=XYZ /mypath vfat noauto,[...]
/mypath/main /newplace none bind,noauto 0 0
/newplace
現在インストールするには、2つのコマンドを使用する必要があります。
mount /mypath
mount /newplace
私も両方umount
になるはずです。
mount
これを1つの(または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