Cần sửa quyền truy cập tệp trong thư mục nhà của người dùng


24

Có ai có một công cụ hoặc tập lệnh sẽ sửa chữa đệ quy các quyền của tập tin trên một thư mục không?

Trên máy Ubuntu Linux, một loạt các tệp đã được sao chép vào đĩa USB với đầy đủ 777 quyền (người dùng, nhóm, người khác - đọc, ghi, thực thi) do lỗi. Tôi muốn đặt chúng trở lại trong thư mục người dùng đã sửa.

Thư mục phải là 775 và tất cả các tệp khác có thể là 664. Tất cả các tệp là hình ảnh, tài liệu hoặc MP3, vì vậy không ai trong số chúng cần phải được thực thi. Nếu bit thư mục được thiết lập thì nó cần thực thi, thông minh khác nó chỉ cần người dùng và nhóm, đọc và viết.

Tôi đoán rằng nó đáng để kiểm tra nếu một tiện ích như vậy tồn tại trước khi hack cùng một tập lệnh shell :)


Câu trả lời:


51

Cái này cần phải dùng mẹo:

find /home/user -type d -print0 | xargs -0 chmod 0775
find /home/user -type f -print0 | xargs -0 chmod 0664

1
+1 để sử dụng -print0 / xargs -0 :-).
sleske

14

tìm có thể thực hiện thủ thuật một mình với -exec:

find /home/user -type f -exec chmod 0664 {} \;
find /home/user -type d -exec chmod 0775 {} \;

để ngăn chặn việc tìm kiếm từ một chmod cho mỗi mục:

find /home/user -type f -exec chmod 0664 {} +
find /home/user -type d -exec chmod 0775 {} +

(điều này thực sự gọi chmod một lần với danh sách tất cả các tệp dưới dạng tham số thay vì một chmod trên mỗi tệp)


6
Chậm hơn so với sử dụng xargs, vì bạn đang sử dụng chmod cho mọi tệp, trong đó xargs sẽ chạy quy trình chmod với càng nhiều tệp càng tốt trên một dòng lệnh. Trên một cây rất lớn, điều này có thể tạo ra sự khác biệt công bằng.
David Pashley

1
Ngoài ra, print0 / xargs -0 sẽ xử lý các tên tệp thậm chí rất kỳ lạ; không chắc chắn về find -exec.
sleske

8

Câu trả lời này sẽ không giải quyết được vấn đề của bạn, nhưng ai đó có thể thấy nó hữu ích cho một vấn đề tương tự khi các tệp có ít quyền hơn họ nên làm.

# chmod -R . u=rwX,g=rX,o=rX

Phép thuật là sự cho phép X, chứ không phải x. Trang chủ chmod mô tả nó như vậy:

chỉ thực hiện / tìm kiếm nếu tệp là một thư mục hoặc đã có quyền thực thi đối với một số người dùng

Điều này không phù hợp trong trường hợp của bạn vì các tệp của bạn có quyền thực thi, do đó, sẽ khớp với thử nghiệm thứ hai.


1
g nên là rwX cho 775 và 664.
aventurin

1

Tôi đã tạo một kịch bản từ giải pháp của freiheit, nó thêm kiểm tra đối số cơ bản.

#!/bin/sh

if [ $# -lt 1 ]; then
    echo "USAGE: $0 <path>"
    exit 1
fi

find $1 -type d -print0 | xargs -0 chmod 0755
find $1 -type f -print0 | xargs -0 chmod 0644

Ý tưởng tốt. Tuy nhiên, dòng thứ hai sẽ xuất hiện lỗi khi mục tiêu là một thư mục : chmod: missing operand after ‘0644’. Tôi có thể đề nghị bọc các câu lệnh tìm bằng một kiểm tra để xem liệu mục tiêu có tồn tại không? if [ -d $1 ]; then find $1 -type d -print0 | xargs -0 chmod 0755; fi; if [ -f $1 ]; then find $1 -type f -print0 | xargs -0 chmod 0644; fi
Đánh bại

Nó gần như đúng; nhưng nếu mục tiêu là một thư mục, bạn đã quên chmod các tệp trong đó và nếu đó là một tệp, bạn chỉ cần chmod tệp đó.
sean

0

Trong trường hợp bạn đang sử dụng ssh, tốt nhất là không sửa đổi ~/.sshquyền.

DIR=/home/user
find $DIR -type d -not -path "$DIR/.ssh" -print0 | xargs -0 chmod 0775
find $DIR -type f -not -path "$DIR/.ssh/*" -print0 | xargs -0 chmod 0664

0

Tôi đã tạo một tập lệnh bash thực sự đơn giản vào ngày khác bởi vì tôi cần sửa các quyền. Tại sao không có tiện ích chính thức để đặt lại các quyền cơ bản, không root, tệp và thư mục?

Kịch bản sử dụng find đến 755 tất cả các thư mục và 644 thư viện. Sau đó, nó kiểm tra từng tệp với readelf để xem nó có tiêu đề elf nhị phân không. Nếu không, nó sẽ quét trong hai ký tự đầu tiên cho shebang #!. Nó 755 những trường hợp đó và 644 mọi thứ khác sau khi nó kiểm tra xem liệu tập tin đã có quyền phù hợp chưa.

Các trường hợp đặc biệt được xử lý với một ngoại lệ như các *.baktập tin bị bỏ qua.

#!/bin/bash
read -r -p "Correct file and folder permissions? [y/N] " chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
  echo "Processing ..."
  find -H $(pwd) -type d -exec chmod 0755 {} \;
  # set dirs to 755
  find -H $(pwd) -type f \( -iname '*.so.*' -o -iname '*.so' \) -exec chmod 0644 {} \;
  # libs
  IFS=$'\n'
  for value in $(find -H $(pwd) -type f ! \( -iname '*.so.*' -o -iname '*.so' -o -iname '*.bak' \) -printf '%p\n'); do
    tstbin=$(readelf -l "$value" 2>/dev/null | grep -Pio 'executable|shared')
    if [ -z "$tstbin" ]; then
      tstbat=$(cat "$value" | head -c2 | grep -io '#!')
      if [ -n "$tstbat" ]; then
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "755" ]; then
          chmod 755 $value
          echo "Set script  755 $value"
          # set batch to 755
        fi
      else
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "644" ]; then
          chmod 644 $value
          echo "Set regular 644 $value"
          # set regular files to 644
        fi
      fi
      # above aren't elf binary
    else
      perm=$(stat -c '%a' "$value")
      if [ "$perm" != "755" ]; then
        chmod 755 $value
        echo "Set binary  755 $value"
        # set elf binaries to 755
      fi
    fi
  done
  unset IFS
  # process linux permissions for files and folders
else
  echo "Aborted."
fi

0

Tôi tìm thấy một giải pháp vỏ C đơn giản hóa. Đây có thể không phải là bằng chứng hoàn toàn ngu ngốc nhưng sẽ hoạt động cho hầu hết các thư mục. Nó giả sử lệnh 'tệp' Unix hoạt động và tìm tệp thực thi để đặt lại chúng để cấp quyền thực thi:

find /home/user -type d | xargs chmod 0775
find /home/user -type f | xargs -0 chmod 0664
find /home/user -type f -exec file {} \; | grep executable | cut -d":" -f1 | xargs chmod 0775

1
Điều này không chỉ lặp lại một số câu trả lời, nó giới thiệu một lỗi và chức năng mà OP không yêu cầu.
RalfFriedl

0

Một thay thế, không trả lời chính xác yêu cầu ban đầu, nhưng nhiều khả năng OP dự định, là chỉ định các quyền một cách tượng trưng. Ví dụ, tôi cho rằng OP muốn "xóa quyền truy cập ghi cho công chúng và xóa quyền thực thi khỏi tất cả các tệp".

Điều này là có thể nếu bạn sử dụng biểu diễn cho phép biểu tượng.

  • ow là "xóa quyền truy cập ghi từ công chúng" ("o" - những người khác, "-" - xóa, "w" - ghi)
  • ax là "remove exec cho mọi người chỉ trên các tập tin" ("a" - all, "-" - remove, "x" - exec)

Viết nó ra theo cách này thay vì cài đặt rõ ràng "0664", bạn tránh vô tình cho phép thêm quyền đối với các tệp đã bị khóa trước đó. Ví dụ: nếu một tệp là 0770, nó sẽ không trở thành 0664 do nhầm lẫn.

Để thực hiện yêu cầu đầu tiên, bạn chỉ cần sử dụng chmod:

chmod --recursive o-w $dir

Để làm yêu cầu thứ hai:

find $dir -type f -exec chmod a-x {} +

Hoặc để làm cả hai:

find $dir -type f -exec chmod a-x,o-w {} +
find $dir -type d -exec chmod o-w {} +
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.