パスの下に入れ子になったすべてのディレクトリを削除します。

パスの下に入れ子になったすべてのディレクトリを削除します。

次の条件を考えてみましょう。

  • いろいろあります入れ子になった多くのフォルダ/ファイルがインストールされました/mnt
    sdb      8:16   0   300G  0 disk
    ├─sdb1   8:17   0   256M  0 part /mnt/1/1
    ├─sdb2   8:18   0 199.7G  0 part /mnt/2
    └─sdb3   8:19   0   100G  0 part /mnt/3/1/2
    
  • /dev/sdbたとえば、どのデバイスがインストールされているかわからないとします/mnt(無人スクリプトで使用したいため)。
  • マウントディレクトリへのパスも不明です。
  • not mountedエラーが原因でプロセスを中断しないでください。

私が試した結果の説明は次のとおりです。

$ umount --all-targets --recursive /mnt; lsblk /dev/sdb
umount: /mnt: not mounted
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sdb      8:16   0   300G  0 disk
├─sdb1   8:17   0   256M  0 part /mnt/1/1
├─sdb2   8:18   0 199.7G  0 part /mnt/2
└─sdb3   8:19   0   100G  0 part /mnt/3/1/2

$ umount --all-targets --recursive /mnt/*/**; lsblk /dev/sdb
umount: /mnt/2/boot: not mounted
umount: /mnt/2/ostree: not mounted
umount: /mnt/3/1: not mounted
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sdb      8:16   0   300G  0 disk
├─sdb1   8:17   0   256M  0 part
├─sdb2   8:18   0 199.7G  0 part /mnt/2
└─sdb3   8:19   0   100G  0 part /mnt/3/1/2

$ umount --all-targets --recursive /mnt/*?; lsblk /dev/sdb
umount: /mnt/1: not mounted
umount: /mnt/3: not mounted
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sdb      8:16   0   300G  0 disk
├─sdb1   8:17   0   256M  0 part /mnt/1/1
├─sdb2   8:18   0 199.7G  0 part
└─sdb3   8:19   0   100G  0 part /mnt/3/1/2

$ umount --all-targets --recursive /mnt/*/**?; lsblk /dev/sdb
umount: /mnt/2/boot: not mounted
umount: /mnt/2/ostree: not mounted
umount: /mnt/3/1: not mounted
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sdb      8:16   0   300G  0 disk
├─sdb1   8:17   0   256M  0 part
├─sdb2   8:18   0 199.7G  0 part /mnt/2
└─sdb3   8:19   0   100G  0 part /mnt/3/1/2

追加のパッケージをインストールせずにこれを行うための良い方法はありますか?

答え1

もっと良い方法があるか教えてください!

私は他の人を助けるために私の結果を投稿します。

  1. 好奇心から、私はこれがnot mountedエラーを引き起こさないので非常に役に立つと思いましたが、これはデバイス名が知られており、パーティション/ディスクセクションごとにマウントポイントがないか1つの場合にのみ機能します。(参考として追加するとインストールされ--all-targetsていないエラーが発生する可能性があるため、抑制するのは|| true悪い習慣です):

    $ umount /dev/sdb?*
    

    代わりに、パーティション/ディスクセクションごとに複数のマウントポイントを処理するために、ディスク上のすべてのマウントポイントを自動的にアンマウントする方法を考えました。

    $ lsblk --noheadings --output MOUNTPOINTS /dev/sdb | xargs -r umount
    
  2. しかし、元の質問の問題を解決するために、次のように考えました。

    $ umount $(df -h --output=target | grep /mnt)
    

    何かがインストールされている場合にのみ機能することがわかりました。ここでは、より正確な一致を提供し、インストールされている場合にのみ削除される拡張バージョンがあります。

    $ df -h --output=target | grep -w /mnt | xargs -r umount
    

    これはさらに調整できます。以前のバージョンでは、ディスクが複数の場所にマウントされている場合は、すべてのディレクトリを一覧表示できませんでした。別の方法で問題を解決してください。

    $ lsblk --output MOUNTPOINTS | grep -w /mnt | xargs -r umount
    

答え2

私は次を使うでしょう:

cd /mnt
find -type d -exec mountpoint {} \;|grep -v not|cut -d" " -f1|tac|xargs umount

これにより、/ mntの下にインストールされているすべてのディレクトリがアンマウントされます。それはあなたが望むことだと思います。これには、マウントポイント(/ mntの下のマウントポイントを除く)のデバイスやパスに関する知識は必要ありません。マウントされたマウントポイントでのみ実行されます。

この方法は、デバイスを推測するのではなくマウントポイントを探して、デバイスが/ mntにマウントされていることを確認することです。ループマウントとネットワークマウントだけでなく、ディスクデバイスを使用したマウントも処理します。

find -type d効率のためにディレクトリを検索します(ファイルとディレクトリがバインドマウント可能である可能性がありますが、わかりません)。 tac は順序を変更するので、まず階層の下のマウントポイントをアンマウントします。

答え3

リポジトリベンダーからこれを得て、bashで動作します。

MOUNTDIR=/mnt

# Sort MOUNTDIR to unmount nested filesystems first
if [[ "$OS" == "AIX" ]]
then
  KEYS=$(
  for KEY in ${!MOUNTDIR[@]}
  do
    echo "${MOUNTDIR[$KEY]}:::$KEY"
  done | sort | awk -F::: '{print $2}'
  )
else
  KEYS=$(
  for KEY in ${!MOUNTDIR[@]}
  do
    echo "${MOUNTDIR[$KEY]}:::$KEY"
  done | sort -r | awk -F::: '{print $2}'
  )
fi

for OLDLV in $KEYS
do
  if [[ "$OS" == "AIX" ]]
  then
    echo "/usr/sbin/fuser -k ${MOUNTDIR[$OLDLV]}"
    if [[ -v COMMIT ]]; then /usr/sbin/fuser -k ${MOUNTDIR[$OLDLV]}; fi
    echo "umount ${MOUNTDIR[$OLDLV]}"
    if [[ -v COMMIT ]]; then umount ${MOUNTDIR[$OLDLV]}; fi
  else
    echo "fuser -kmMs ${MOUNTDIR[$OLDLV]}"
    if [[ -v COMMIT ]]; then fuser -kmMs ${MOUNTDIR[$OLDLV]}; fi
    echo "umount ${MOUNTDIR[$OLDLV]}"
    if [[ -v COMMIT ]]; then umount ${MOUNTDIR[$OLDLV]}; fi
  fi
done

関連情報