Bash 스크립트에 볼륨이 마운트되어 있는지 확인하는 가장 좋은 방법은 무엇입니까?


103

Bash 스크립트에 볼륨이 마운트되어 있는지 확인하는 가장 좋은 방법은 무엇입니까?

내가 정말로 원하는 것은 다음과 같이 사용할 수있는 방법입니다.

if <something is mounted at /mnt/foo> 
then
   <Do some stuff>
else
   <Do some different stuff>
fi

나는 이것을 직접하기 위해 스크립트를 작성하려고했습니다. 내 첫 번째 생각은 / etc / mtab에서 정보를 얻는 것입니다. 그러나 더 직접적인 방법이 있는지 아직 배쉬 북을 살펴 보지 않았습니다.
3dinfluence

@ 3dinfluence - 그래 난이 시간이 오래 전부터 알고 있지만 /etc/mtab, /proc/mounts연결되어 있습니다 /proc/self/mounts. (Fedora 20에
이상적

서버 폴트 , 스택 오버 플로우유닉스 및 리눅스 스택 교환 에 대해서도 비슷한 질문이 있습니다.
사샤

답변:


113

/etc/mtab일치하지 않을 수 있으므로 사용하지 마십시오 .

배관 mount이 그렇게 복잡 할 필요는 없으므로 피하십시오 .

간단히:

if grep -qs '/mnt/foo ' /proc/mounts; then
    echo "It's mounted."
else
    echo "It's not mounted."
fi

(뒤의 공백 /mnt/foo은 예를 들어 일치를 피하는 것 /mnt/foo-bar입니다.)


7
말할 것도없이, 마운트 포인트가 웨지되면 마운트 호출이 중단 될 수 있습니다.
Chad Huneycutt

8
Linux에 적합하며 freebsd 또는 solaris에는 적합하지 않습니다.
chris

4
이건 사실이야, 크리스 질문은 리눅스로 태그되었지만.
Dan Carley

3
나는 이것이 철학적 인 질문이라고 생각합니다. 가능하다면 물건을 휴대 할 수있게해야합니까, 아니면 세계의 모든 윈도우 / 리눅스를 실행하고 그에 따라 행동한다고 ​​가정해야합니까?
chris

18
실제로 '/ mnt / foo'를 테스트해야합니다. 공백이 있거나 eg라는 볼륨을 마운트 한 경우 오 탐지가 발생할 수 있습니다. 'fooks'. 방금 'lmde'와 'lmde-home'이라는 두 개의 마운트 지점으로 문제가 발생했습니다.
marlar

58
if mountpoint -q /mnt/foo 
then
   echo "mounted"
else
   echo "not mounted"
fi

또는

mountpoint -q /mnt/foo && echo "mounted" || echo "not mounted"

4
정보 용 : mountpointUbuntu / Debian의 "initscripts"패키지에서 시작됩니다.
blueyed

1
나를 위해 작동하지 않았다-:-(
Wilf

이것은 나의 방랑자가 전화하는 부름입니다.
dhill

문제 mountpoint는 실제로 마운트 지점이 마운트되어 있는지 확인하지만 장치가 마운트되어 있는지 확인하지 않는다는 것입니다. -x옵션 과 함께 장치가 전달 되면 주 / 부 장치 번호는 알려 주지만 마운트되어 있지는 않습니다.
vegatripy

@blueyed 데비안 버스터에서 제공되는 패키지util-linux
elboulangero

18

findmnt -rno SOURCE,TARGET "$1"다른 답변의 모든 문제를 피하십시오. 단 하나의 명령으로 작업을 깔끔하게 수행합니다.


다른 접근 방식에는 다음과 같은 단점이 있습니다.

  • grep -q그리고 grep -s여분의 불필요한 단계이며, 모든 곳에서 지원되지 않습니다.
  • /proc/\* 모든 곳에서 지원되지는 않습니다.
  • mountinfo / proc /.를 기반으로합니다.
  • cut -f3 -d' ' 경로 이름에서 공백을 엉망으로 만듭니다
  • 마운트 의 공백을 구문 분석하는 데 문제가 있습니다. 맨 페이지는 이제 말합니다 :

.. 리스팅 모드는 이전 버전과의 호환성을 위해서만 유지됩니다.

보다 강력하고 사용자 정의 가능한 출력을 얻으 려면 특히 스크립트에서 findmnt (8)를 사용 하십시오.


배쉬 기능 :

#These functions return exit codes: 0 = found, 1 = not found

isMounted    () { findmnt -rno SOURCE,TARGET "$1" >/dev/null;} #path or device
isDevMounted () { findmnt -rno SOURCE        "$1" >/dev/null;} #device only
isPathMounted() { findmnt -rno        TARGET "$1" >/dev/null;} #path   only

#where: -r = --raw, -n = --noheadings, -o = --output

사용 예 :

if isPathMounted "/mnt/foo bar";      #Spaces in path names are ok.
   then echo "path is mounted"
   else echo "path is not mounted"
fi

if isDevMounted "/dev/sdb4"; 
   then echo "device is mounted"
   else echo "device is not mounted"
fi

#Universal:
if isMounted "/mnt/foo bar"; 
   then echo "device is mounted"
   else echo "device is not mounted"
fi

if isMounted "/dev/sdb4";
   then echo "device is mounted"
   else echo "device is not mounted"
fi

1
어쨌든 리눅스 고유의 경우 이것이 실제로 가장 좋은 방법입니다. 나는 findmnt(8)명령을 보았지만 결코 그와 함께 놀지 않았습니다. 솔직히 리눅스 상자에서 (또는 명령을 사용할 수있는)이 유형의 작업을 수행하거나 새로운 스크립트를 작성하는 일부 스크립트를 업데이트하려는 경우 이것이 내가하는 일입니다.
Pryftan

1
encfs의 findmnt경우 매개 변수와 함께 제공되어야합니다 --source encfs. 그렇지 않으면 상위 마운트 로 폴백 되므로 항상 마운트 될 디렉토리를 고려합니다.
Burkart

이것은 또한보다 낫다 grep마운트 경로가 이상한 경우, 당신이 잘못된 반응을 얻을 수 있기 때문에 솔루션 : 나는 마운트 경우 예 /dev/mmcblk0p1~/mnt/dev/sda1, 나는 일이 잘못 할 수 /dev/sda1명령에 의해 장착되어있다 mount | grep '/dev/sda1'. 를 사용하여 오 탐지를 얻을 수 없습니다 findmnt. 좋은 대답입니다!
Cody Piersall

7

이와 같은 스크립트는 이식성이 없습니다. 유닉스의 더러운 비밀은 커널 만이 파일 시스템의 위치를 ​​알고 있으며 / proc (휴대용 아님)과 같은 짧은 것은 결코 대답하지 않을 것입니다.

나는 일반적으로 df를 사용하여 서브 디렉토리의 마운트 지점과 파일 시스템이 무엇인지 발견합니다.

예를 들어 (재 / AT & T ksh / bash와 같은 posix 쉘 필요)

case $(df  $mount)
in
  $(df  /)) echo $mount is not mounted ;;
  *) echo $mount has a non-root filesystem mounted on it ;;
esac

킨다는 유용한 정보를 알려줍니다.


1
이 질문은 리눅스로 태그되어 있으므로 이식성이 없어도됩니다
Rory

6

다음은 내 rsync 백업 cron-job 중 하나에서 사용하는 것입니다. / backup이 마운트되어 있는지 확인하고 마운트되어 있지 않으면 마운트를 시도합니다 (드라이브가 핫 스왑 베이에 있고 시스템에 없을 수도 있으므로 실패 할 수 있음)

참고 : 다음은 Linux에서만 작동합니다. / proc / mounts를 greps하기 때문에보다 이식성있는 버전은 'mount | grep / backup ', Matthew의 답변 에서처럼 ..

  만약 ! grep -q / backup / proc / mounts; 그때
    만약 ! 마운트 / 백업; 그때
      에코 "실패"
      1 번 출구
    fi
  fi
  에코 "성공했습니다."
  # 여기에 물건을

2
좋은 위생 검사 대안으로 찬성했습니다.
Dan Carley

아마도이 방법은 Matthew Bloch의 대답과 같은 문제에 처할 것입니다.
mwfearnley

예, "Eliptical view"에서 언급 한 파일 이름 공간 문제를 제외하고 (추출 된 필드가 아니라 전체 라인을 잡습니다). 인수를 인용하는 것이 당신이 할 수있는 일이라는 것을 어떻게 든 잊어 버리지 않는 한 하위 문자열 문제는 큰 문제가 아닙니다. 예를 들어 grep -q ' /backup ' /proc/mounts또는 mount | grep -q ' /backup '. 당신의 GREP 지원하지 않는 경우 또는 / dev / null로 리디렉션 -q(이 입니다 요즘 그렙에 대한 POSIX 사양에).
cas

2

마운트하려면 어쨌든 디렉토리가 있어야합니다. 마운트 된 디렉토리는 항상 사용되지 않는 이상한 파일 이름으로 가짜 파일을 작성하고 존재 여부를 확인하는 것이 었습니다. 파일이 있으면 해당 지점에 마운트 된 것이 없습니다 ...

나는 이것이 네트워크 드라이브 또는 이와 유사한 것을 마운트하는 데 효과가 없다고 생각합니다. 플래시 드라이브에 사용했습니다.


2

장치 번호를 비교하는 것은 어떻습니까? 난 그냥 대부분의 생각하려고했다 밀교 방법 ..

#!/bin/bash
if [[ $(stat -c "%d" /mnt) -ne $(stat -c "%d" /mnt/foo) ]]; then
    echo "Somethin mounted there I reckon"
fi

내 논리에 결함이 있습니다 ...

기능으로서 :

#!/usr/bin/bash
function somethingMounted {
        mountpoint="$1"
        if ! device1=$(stat -c "%d" $mountpoint); then
                echo "Error on stat of mount point, maybe file doesn't exist?" 1>&2
                return 1
        fi
        if ! device2=$(stat -c "%d" $mountpoint/..); then
                echo "Error on stat one level up from mount point, maybe file doesn't exist?" 1>&2
                return 1
        fi

        if [[ $device1 -ne $device2 ]]; then
                #echo "Somethin mounted there I reckon"
                return 0
        else
                #echo "Nothin mounted it seems"
                return 1
        fi
}

if somethingMounted /tmp; then
        echo "Yup"
fi

stat는 오류도 표시하므로 에코 오류 메시지는 중복 될 수 있습니다.


사실, 아마 내가 :-( 생각으로 파일이없는 소설로 ...이 있는지 확인하기 위해 먼저 각 호출에 대해 통계의 종료 상태를 확인해야 할 것입니다
카일 브랜

1

주어진 디렉토리가 다른 마운트 지점 내의 서브 디렉토리 인 유스 케이스를 만족시키는 것은 없습니다. 예를 들어, 호스트 : / real_thing에 대한 NFS 마운트 인 / thing이있을 수 있습니다. / proc / mounts / etc / mtab에서 grep을 사용하면 존재하지 않는 마운트 지점을 찾게되므로 'mount'가 작동하지 않습니다. 예를 들어, / thing / thingy는 마운트 지점이 아니지만 / thing은 호스트 : / real_thing에 마운트됩니다. 여기서 투표 한 가장 좋은 답변은 실제로 "디렉토리 / 볼륨이 마운트되어 있는지 확인하는 가장 좋은 방법"이 아닙니다. 나는 'df -P'(-P POSIX 표준 모드)를보다 깔끔한 전략으로 사용하여 찬성 투표했습니다.

dev=`df -P /thing/thingy | awk 'BEGIN {e=1} $NF ~ /^\/.+/ { e=0 ; print $1 ; exit } END { exit e }'` && {
    echo "Mounted via: $dev"
} || {
    echo "Not mounted"
}

이것을 실행 한 결과는 다음과 같습니다.

Mounted via: host:/real_thing

실제 마운트 지점이 무엇인지 알고 싶다면 문제 없습니다.

mp=`df -P /thing/thingy | awk 'BEGIN {e=1} $NF ~ /^\/.+/ { e=0 ; print $NF ; exit } END { exit e }'` && {
    echo "Mounted on: $mp"
} || {
    echo "Not mounted"
}

해당 명령의 출력은 다음과 같습니다.

Mounted on: /thing

이것은 임의의 디렉토리 또는 파일 목록을 통해 chroot 외부, chroot 내에서 마운트 지점을 미러링하는 일종의 chroot를 작성하려는 경우 매우 유용합니다.


1

이것을 가져서 죄송하지만 나는 이것이 매우 유용하다고 생각합니다.

if awk '{print $2}' /proc/mounts | grep -qs "^/backup$"; then
    echo "It's mounted."
else
    echo "It's not mounted."
fi

이것은 / proc / mounts의 두 번째 열을 얻습니다 (2 번째 열 = 마운트 지점).

그런 다음 출력을 잡습니다. ^ 및 $를 참고하면 / backup이 / mnt / backup 또는 / backup-old 등과 일치하지 않습니다.


0

마운트 지점에 grep / etc / mtab이 있습니까?


1
/가 읽기 전용이므로 mount -n을 사용할 때와 같이 mtab이 오래되었거나 마운트로 간단히 업데이트되지 않을 수 있습니다.
chris

나는 동의하지만, 그것은 처음부터 시작하는 것처럼 보였다.
Ophidian


0

이것이 리눅스 질문이지만, 쉽게 수행 할 수있는 이유는 무엇입니까?

의 매뉴얼 페이지는 grep말합니다 :

이식 가능한 쉘 스크립트는 -q와 -s를 모두 피해야하며 /dev/null대신 표준 및 오류 출력을 리디렉션해야 합니다.

그래서 나는 다음 해결책을 제안합니다.

if grep /mnt/foo /proc/mounts > /dev/null 2>&1; then
        echo "Mounted"
else
        echo "NOT mounted"
fi

3
대부분의 UNIX 시스템은 / proc 디렉토리 파일 시스템을 제공하지 않습니다
드미트리 Chubarov

@DmitriChubarov 실제로. 이식성의 개념이 아이러니하지 않습니까? 그리고 어쩌면 더 최신 업데이트입니다하지만 -q-s(- 나는 때 발생하는 어떤 변화를 추적 유지되지했습니다 지금은 아니지만 전) 어쨌든 어떤 이식성 문제가있을해서는 안 POSIX에 의해 지정됩니다.
Pryftan

0

이보다 더 복잡해야합니까?

mount \
    | cut -f 3 -d ' ' \
    | grep -q /mnt/foo \
  && echo "mounted" || echo "not mounted"

1
grep -q /mnt/foo마운트 포인트 /mnt/food와 일치합니다 /not/mnt/foo... 어떻 grep -qx /mnt/foo습니까?
rakslice

@ rakslice : 작동하지 않습니다. -x전체 줄이 일치하는 경우에만 grep을 일치시킵니다.
mivk

1
cut -f 3 -d ' '마운트 경로에 파일 이름에 공백이 있으면 넘어집니다.
Elliptical view

0

확인중인 볼륨에 대해 알고있는 내용에 따라 다릅니다.

최근에 조사한 결과 특정 플래시 드라이브가 마운트되었는지 여부를 확인하려는 경우 가장 쉽게 작동하는 것은 / dev / disks / by-label /의 존재 여부를 확인하는 것입니다. 장치가 연결되어 있으면 udev 스크립트는 링크가 존재하는지 확인하고 장치를 분리하면 제거됩니다.

(이것은 이식성이 뛰어나지 않습니다. 그러나 많은 현대 Linux 배포판에서 작동하며 질문은 Linux로 태그 지정되었으며 지금까지 언급 한 것과는 완전히 다른 접근 방식이므로 가능성을 확장합니다.)


0

마운트 포인트 아래에 파일을 작성한 check_mount다음 존재하는지 테스트하십시오.

if [[ -f /something/check_mount ]]; then
   echo "Mounted
   RC=$?
else
   Echo "Not mounted"
   RC=0
fi
exit $RC

-1

chef-client가 실행될 때 볼륨이 이미 마운트되어 있기 때문에 실행이 실패 할 것이기 때문에 Chef에서 idempotence를 위해이 작업을 수행해야했습니다. 필자가 이것을 작성했을 때 Chef mount리소스에는 필요한 방식으로 속성과 작동하지 않는 일종의 버그가 있으므로 execute리소스를 대신 사용하여 볼륨을 마운트했습니다 . 내가 한 방법은 다음과 같습니다.

if not node['docker-server']['mountpoint'] == "none"
  execute "set up mount" do
    user "root"
    command "mount -t ext4 #{node['docker-server']['mountpoint']} #{node['docker-server']['data-dir']}"
    not_if "grep -qs #{node['docker-server']['data-dir']} /proc/mounts"
  end
end

혼란 스러울 경우 속성 파일에 다음이 있습니다.

default['docker-server']['mountpoint'] = "/dev/vdc"
default['docker-server']['data-dir'] = "/data"

if not node['docker-server']['mountpoint'] == "none"의 일부 case서버의 마운트 포인트에 마운트 지점의 기본값을 지정하지 않은 경우 문 none.


... 그리고 이것은 원래 질문과 어떤 관련이 있습니까?!?
Massimo

요리사 레시피 주석과 원래 질문의 관계는 사람들이 점점 자동화로 나아가고 있다는 것입니다. 따라서 누군가가 Chef 레시피 에서이 작업을 수행하는 방법을 궁금해하면 여기에 답변이 있습니다. 인생에는 두 가지 옵션이 있습니다. 1) 최소한으로 행동하고 일부 사람들을 행복하게 만들고 2) 추가 마일을갑니다 따라서 게시물을 표시하지 않고 수락 된 답변을 지원하는 추가 정보 인 게시물을 승인하십시오.
KLaw

문제는 bash 스크립트에 관한 것이고, 귀하의 대답은 Chef 스크립트에 관한 것입니다. 누군가에게 유용 할 수도 있지만 여전히 질문과 관련이 없습니다.
Massimo

@KLaw '따라서 게시물을 표시하지 않고 수락 된 답변을 뒷받침하는 추가 정보입니다.' 나는 동의하며 나는 보통 다운 투표를하지 않으며 (나도 여기에 있지 않다) 당신이 그런 유형의 문제에 문제가 있다면 당신은 다른 포인트에 추가로 그것을 추가해야할까요? 다른 의견을 저장할 수도 있습니다. 그러나 자동화에 관해서는 정확히 bash 스크립트가 허용하는 것이므로 요점을 알 수 없습니다. 물론 저의 프로그래머는 위의 스크립트가
끔찍
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.