Cách tốt nhất để kiểm tra xem một ổ đĩa có được gắn trong tập lệnh Bash không?


103

Cách tốt nhất để kiểm tra xem một ổ đĩa có được gắn trong tập lệnh Bash không?

Điều tôi thực sự thích là một phương pháp mà tôi có thể sử dụng như thế này:

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

Tôi chỉ định viết một kịch bản để tự làm việc này. Suy nghĩ đầu tiên của tôi là lấy thông tin ra khỏi / etc / mtab Nhưng tôi vẫn chưa xem qua các cuốn sách bash của mình để xem liệu có cách nào trực tiếp hơn không.
3dinfluence

@ 3dinfluence - vâng tôi biết điều này từ rất lâu rồi, nhưng /etc/mtab, /proc/mountsđược liên kết đến /proc/self/mounts. (ít nhất là trên Fedora 20)
Wilf

Các câu hỏi tương tự là trên Server Fault , Stack OverflowUnix & Linux Stack Exchange .
Sasha

Câu trả lời:


113

Tránh sử dụng /etc/mtabvì nó có thể không nhất quán.

Tránh đường ống mountvì nó không quá phức tạp.

Đơn giản:

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

(Không gian sau /mnt/foolà để tránh kết hợp, ví dụ /mnt/foo-bar.)


7
Chưa kể, một cuộc gọi để gắn kết có thể bị treo nếu điểm gắn kết được nêm.
Chad Huneycutt

8
Tốt cho linux, không phải cho freebsd hoặc solaris.
chris

4
Đây là sự thật, chris. Mặc dù câu hỏi đã được gắn thẻ linux.
Dan Carley

3
Tôi đoán đây là một câu hỏi triết học - chúng ta nên cố gắng làm cho mọi thứ trở nên di động nếu có thể hay chúng ta chỉ nên cho rằng tất cả các thế giới đang chạy windows / linux và hành động phù hợp?
chris

18
Trên thực tế, bạn nên kiểm tra '/ mnt / foo', nghĩa là. với một khoảng trắng hoặc bạn có thể nhận được dương tính giả nếu bạn đã gắn một âm lượng có tên, vd. 'Fooks'. Tôi vừa gặp vấn đề đó với hai điểm gắn kết, 'lmde' và 'lmde-home'.
tuyên bố

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

hoặc là

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

4
Chỉ để biết thông tin: mountpointbắt nguồn từ gói "initscripts" trong Ubuntu / Debian.
xanh

1
Không làm việc cho tôi - :-(
Wilf

Đây là cuộc gọi, mà Vagrant của tôi bị treo.
dhill

Vấn đề với mountpointlà nó kiểm tra, trên thực tế, nếu một điểm gắn kết được gắn, nhưng không phải nếu một thiết bị được gắn kết. Nếu một thiết bị được thông qua với -xtùy chọn, nó sẽ cho bạn biết số thiết bị chính / phụ, nhưng không phải nếu nó được gắn.
ăn chay

@blueyed Trong Debian Buster, nó được cung cấp bởi góiutil-linux
elboulangero

18

findmnt -rno SOURCE,TARGET "$1"tránh tất cả các vấn đề trong các câu trả lời khác Nó hoàn toàn làm công việc chỉ với một lệnh.


Các cách tiếp cận khác có những nhược điểm:

  • grep -qgrep -slà một bước không cần thiết thêm và không được hỗ trợ ở mọi nơi.
  • /proc/\* không được hỗ trợ ở mọi nơi.
  • mountinfo được dựa trên / Proc / ..
  • cut -f3 -d' ' làm rối tung không gian trong tên đường dẫn
  • Phân tích không gian trắng của mount là vấn đề. Bây giờ trang của người đàn ông nói:

.. chế độ liệt kê được duy trì để chỉ tương thích ngược.

Để đầu ra mạnh mẽ hơn và có thể tùy chỉnh, hãy sử dụng findmnt (8), đặc biệt là trong các tập lệnh của bạn.


Hàm Bash:

#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

Ví dụ sử dụng:

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
Đối với Linux cụ thể dù sao đây thực sự là cách tiếp cận tốt nhất. Tôi đã thấy findmnt(8)lệnh nhưng tôi không bao giờ thực sự chơi với nó. Thành thật mà nói, nếu tôi cập nhật một số tập lệnh thực hiện loại điều này (hoặc tạo tập lệnh mới) trên hộp Linux (hoặc nơi có sẵn lệnh) thì đây là việc tôi sẽ làm.
Pryftan

1
Lưu ý rằng đối với các bảng mã, findmntphải được cung cấp với tham số --source encfs, nếu không, nó sẽ luôn xem thư mục sẽ được gắn kết vì nó rơi trở lại giá trị cha.
Burkart

Đây cũng là tốt hơn so với các grepgiải pháp bởi vì nếu một con đường núi là lạ, bạn có thể nhận dương tính giả: ví dụ như nếu tôi gắn kết /dev/mmcblk0p1trên ~/mnt/dev/sda1, tôi có thể không đúng điều mà /dev/sda1được gắn bởi các lệnh mount | grep '/dev/sda1'. Tôi không thể có được một dương tính giả bằng cách sử dụng findmnt. Câu trả lời tốt!
Cody Piersall

7

Một kịch bản như thế này sẽ không bao giờ được di động. Một bí mật bẩn thỉu trong unix là chỉ hạt nhân mới biết hệ thống tập tin đang ở đâu và thiếu những thứ như / Proc (không di động), nó sẽ không bao giờ cho bạn câu trả lời thẳng.

Tôi thường sử dụng df để khám phá điểm gắn kết của thư mục con là gì và hệ thống tập tin trong đó là gì.

Chẳng hạn (yêu cầu shell posix như ash / AT & T ksh / bash / etc)

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

Kinda cho bạn biết thông tin hữu ích.


1
Câu hỏi được gắn thẻ linux, vì vậy có lẽ nó không cần phải di động
Rory

6

sau đây là những gì tôi sử dụng trong một trong những công việc định kỳ sao lưu rsync của mình. nó kiểm tra xem nếu / sao lưu được gắn kết và cố gắng gắn kết nếu nó không (nó có thể thất bại vì ổ đĩa nằm trong khoang trao đổi nóng và thậm chí có thể không có trong hệ thống)

LƯU Ý: phần sau chỉ hoạt động trên linux, bởi vì nó greps / Proc / mounts - một phiên bản di động hơn sẽ chạy 'mount | grep / backup ', như trong câu trả lời của Matthew ..

  nếu như ! grep -q / sao lưu / Proc / gắn kết; sau đó
    nếu như ! gắn kết / sao lưu; sau đó
      tiếng vang "thất bại"
      thoát 1
    fi
  fi
  tiếng vang "thành công."
  # làm những thứ ở đây

2
Nâng cao như một sự thay thế kiểm tra vệ sinh tốt.
Dan Carley

Có lẽ phương pháp này gặp vấn đề tương tự như câu trả lời của Matthew Bloch.
mwfearnley

vâng, ngoại trừ vấn đề tên tệp trong không gian được đề cập bởi "Chế độ xem Eliptical" (điều này bao gồm toàn bộ dòng, không chỉ là một trường được trích xuất). Vấn đề chuỗi con không phải là vấn đề lớn trừ khi bạn bằng cách nào đó quên rằng trích dẫn các đối số là điều bạn có thể làm. ví dụ grep -q ' /backup ' /proc/mountshay mount | grep -q ' /backup '. Hoặc chuyển hướng đến / dev / null nếu grep của bạn không hỗ trợ -q( nằm trong thông số POSIX cho grep những ngày này).
cas

2

Vì để gắn kết, dù sao bạn cũng cần phải có một thư mục, được gắn kết, chiến lược của tôi là luôn tạo một tệp không có thật với một tên tệp lạ sẽ không bao giờ được sử dụng và chỉ cần kiểm tra sự tồn tại của nó. Nếu tập tin ở đó, thì không có gì được gắn vào vị trí đó ...

Tôi không nghĩ rằng nó hoạt động để gắn ổ đĩa mạng hoặc những thứ tương tự. Tôi đã sử dụng nó cho các ổ đĩa flash.


2

Làm thế nào về việc so sánh số lượng thiết bị? Tôi chỉ đang cố nghĩ về cách bí truyền nhất ..

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

Có một lỗ hổng trong logic của tôi với điều đó ...

Là một chức năng:

#!/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

Các thông báo lỗi echo có thể là dư thừa, vì stat cũng sẽ hiển thị lỗi.


Trên thực tế, có lẽ sẽ phải kiểm tra trạng thái thoát của stat trước cho mỗi cuộc gọi để đảm bảo tệp có ở đó ... không mới lạ như tôi nghĩ :-(
Kyle Brandt

1

Không ai trong số này thỏa mãn trường hợp sử dụng trong đó một thư mục đã cho là thư mục con trong một điểm gắn kết khác. Ví dụ: bạn có thể có / thứ gắn kết NFS với máy chủ: / real_thing. Sử dụng grep cho mục đích này trên / Proc / mounts / etc / mtab hoặc 'mount' sẽ không hoạt động, bởi vì bạn sẽ tìm kiếm một điểm gắn kết không tồn tại. Ví dụ: / thing / thingy không phải là điểm gắn kết, nhưng / thing được gắn trên máy chủ: / real_thing. Câu trả lời tốt nhất được bình chọn ở đây thực sự KHÔNG phải là "cách tốt nhất để xác định xem thư mục / volumne có được gắn hay không". Tôi sẽ bỏ phiếu ủng hộ bằng cách sử dụng 'df -P' (-P chế độ tiêu chuẩn POSIX) làm chiến lược sạch hơn:

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"
}

Đầu ra từ việc chạy này sẽ là:

Mounted via: host:/real_thing

Nếu bạn muốn biết điểm gắn kết thực sự là gì, không có vấn đề gì:

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"
}

Đầu ra từ lệnh đó sẽ là:

Mounted on: /thing

Điều này rất hữu ích nếu bạn đang cố gắng tạo một số loại chroot phản chiếu các điểm gắn bên ngoài chroot, trong chroot, thông qua một số thư mục hoặc danh sách tệp tùy ý.


1

Xin lỗi vì đã đưa nó lên nhưng tôi nghĩ nó khá hữu ích:

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

Điều này nhận được cột thứ 2 của / Proc / mounts (cột thứ 2 = điểm gắn kết).

Sau đó, nó greps đầu ra. Lưu ý ^ và $, điều này ngăn / sao lưu khớp / mnt / sao lưu hoặc / sao lưu cũ, v.v.


0

grep / etc / mtab cho điểm gắn kết của bạn có thể?


1
mtab có thể bị lỗi thời hoặc đơn giản là không được cập nhật bằng mount, chẳng hạn như khi bạn sử dụng mount -n vì / chỉ đọc.
chris

Tôi đồng ý, nhưng đó dường như là nơi đầu tiên để bắt đầu tìm kiếm.
Ophidian


0

Mặc dù đây là một câu hỏi của Linux, tại sao không làm cho nó di động khi nó được thực hiện dễ dàng?

Trang hướng dẫn sử dụng grepcho biết:

Các kịch bản shell di động nên tránh cả -q và -s và nên chuyển hướng đầu ra tiêu chuẩn và lỗi sang /dev/nullthay thế.

Vì vậy, tôi đề xuất giải pháp sau đây:

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

3
Nhiều hệ thống UNIX không cung cấp hệ thống tập tin / Proc
Dmitri Chubarov

@DmitriChubarov Thật vậy. Điều này làm cho khái niệm về tính di động trở nên mỉa mai phải không? Và có thể đó là bản cập nhật gần đây hơn -q-sđược chỉ định bởi POSIX vì vậy dù sao cũng không có vấn đề về tính di động nào (bây giờ nếu không phải trước đây - tôi đã không theo dõi những thay đổi xảy ra khi nào).
Pryftan

0

Có cần phải phức tạp hơn thế này không?

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

1
grep -q /mnt/foocũng sẽ phù hợp với điểm gắn kết /mnt/food/not/mnt/foo... Còn về grep -qx /mnt/foo?
rakslice

@rakslice: sẽ không hiệu quả. -xlàm cho grep chỉ khớp nếu toàn bộ dòng khớp.
mivk

1
cut -f 3 -d ' 'vấp ngã khi đường dẫn mount có khoảng trắng trong tên tệp.
Chế độ xem hình elip

0

Phụ thuộc vào những gì bạn biết về âm lượng bạn đang kiểm tra.

Trong trường hợp cụ thể mà tôi đã nghiên cứu gần đây, nơi tôi quan tâm để tìm xem một ổ đĩa flash cụ thể đã được gắn chưa, công việc nào dễ dàng nhất là kiểm tra sự tồn tại của / dev / đĩa / by-nhãn /. Nếu thiết bị được cắm, tập lệnh udev đảm bảo liên kết tồn tại (và nó bị xóa khi rút phích cắm thiết bị).

(Tuy nhiên, đây KHÔNG phải là một câu trả lời có tính di động cao; nó hoạt động trên nhiều bản phân phối Linux hiện đại và câu hỏi được gắn thẻ cho Linux và đó là một cách tiếp cận hoàn toàn khác với bất kỳ điều gì được đề cập cho đến khi nó mở rộng các khả năng.)


0

Tạo tập tin theo mountpoint của bạn như thế nào check_mountvà sau đó chỉ kiểm tra nếu nó tồn tại?

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

-1

Tôi đã phải làm điều này trong Chef for idempotence kể từ khi đầu bếp-khách hàng chạy, việc chạy sẽ thất bại do âm lượng đã được gắn. Vào thời điểm tôi viết bài này, mounttài nguyên Chef có một số loại lỗi không hoạt động với các thuộc tính theo cách tôi cần, vì vậy tôi đã gắn âm lượng bằng cách sử dụng executetài nguyên thay thế. Đây là cách tôi đã làm:

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

Trong trường hợp có bất kỳ sự nhầm lẫn nào, trong tệp thuộc tính của tôi, tôi có những điều sau đây:

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

Đây if not node['docker-server']['mountpoint'] == "none"là một phần của casecâu lệnh trong đó nếu điểm gắn kết trên máy chủ không được chỉ định, điểm gắn kết mặc định là none.


... Và điều này có liên quan gì đến câu hỏi ban đầu?!?
Massimo

Mối quan hệ của nhận xét công thức đầu bếp của tôi với câu hỏi ban đầu là mọi người đang ngày càng chuyển sang tự động hóa. Do đó, nếu ai đó đến đây tự hỏi làm thế nào để thực hiện công việc này trong một công thức đầu bếp, họ sẽ có câu trả lời. Trong cuộc sống có hai lựa chọn: 1) Làm tối thiểu và làm cho một số người hạnh phúc, và 2) Đi thêm một dặm. Do đó, thay vì đánh dấu bài viết của tôi xuống, hãy chấp nhận nó cho những gì nó là: thông tin bổ sung hỗ trợ câu trả lời được chấp nhận.
KLaw

Câu hỏi là về kịch bản bash, câu trả lời của bạn là về kịch bản Chef. Mặc dù nó có thể hữu ích cho ai đó, nhưng nó vẫn không liên quan đến câu hỏi.
Massimo

@KLaw 'Do đó, thay vì đánh dấu bài đăng của tôi, hãy chấp nhận nó cho những gì nó là: thông tin bổ sung hỗ trợ câu trả lời được chấp nhận.' Tôi đồng ý và tôi không phải là người thường bỏ phiếu (và tôi cũng không ở đây) nhưng nếu bạn gặp vấn đề với loại điều đó, bạn có thể thêm nó vào như một điểm bổ sung cho các điểm khác của bạn không? Có thể lưu các ý kiến ​​khác. Nhưng đối với tự động hóa đó chính xác là những gì bash script cho phép nên tôi không thấy quan điểm của bạn. Tất nhiên, lập trình viên trong tôi nghĩ rằng kịch bản ở trên thật ghê tởm nhưng đó là vấn đề ngôn ngữ hơn bất cứ thứ gì khác ...
Pryftan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.