하나의 명령으로 여러 개의 중첩 디렉터리를 만들고 모든 권한을 정의하는 방법은 무엇입니까?

하나의 명령으로 여러 개의 중첩 디렉터리를 만들고 모든 권한을 정의하는 방법은 무엇입니까?

Linux에서는 다음 두 명령이 예상대로 작동합니다.

mkdir -m 555 new_directory
mkdir -p a/b/c

그러나 다음은 작동하지 않습니다예상대로:

mkdir -m 555 -p a/b/c

3개의 디렉터리가 생성되었지만 최신 디렉터리에만 555권한이 있습니다. a디렉토리에는 기본 b권한이 있습니다.

그렇다면 제목에 설명된 목표를 어떻게 달성합니까? 가능합니까?

그런데 - 555임의의 사례를 선택했는데 666역시 777실패했습니다 .

답변1

디렉토리를 명시적으로 나열하면(상위 디렉토리가 먼저) 하나의 명령으로 디렉토리를 생성한다는 명시된 목표를 달성할 수 있습니다.

mkdir -m 555 -p a a/b a/b/c

csh 스타일 중괄호 확장을 지원하는 셸을 사용하면 bash작업을 약간 단순화할 수 있지만 가독성이 저하됩니다.

mkdir -m 555 -p a{,/b{,/c}}

하지만 참고하세요.권한의 경우 555두 명령이 모두 실패합니다.상위 디렉터리를 생성해야 하는 경우: 이러한 디렉터리는 쓰기를 허용하지 않는 권한으로 생성되므로 하위 수준 디렉터리를 생성할 수 없습니다.

마지막으로, bash쉘 스크립트는 복잡성을 함수로 래핑하여 단일 명령으로 요청 시 여러 디렉터리를 생성하는 기능을 제공할 수도 있습니다. 그러면 새로 생성된 디렉터리에 권한을 아래에서 위로 적용하려고 시도하므로 쓰기 권한이 없는 디렉터리가 될 수 있습니다.

mkdirs()
{
    local dirs=() modes=() dir old

    # Grab arguments
    [[ "$1" == '-m' ]] && modes=('-m' "$2") && shift 2
    dir=$1

    # Identify missing directories
    while [[ "$dir" != "$old" ]]
    do
        [[ ! -d "$dir" ]] && dirs+=("$dir")
        old="$dir"
        dir="${dir%/*}"
    done

    # Create necessary directories and maybe fix up permissions
    for dir in "${dirs[@]}"
    do
        mkdir -p "${modes[@]}" "$dir" || return 1
        [[ -n "${modes[1]}" ]] && chmod "${modes[1]}" "$dir"
    done
}

mkdirs -m 555 a/b/c

ls -ld a a/b a/b/c
dr-xr-xr-x+ 1 roaima roaima 0 Jan  7 10:01 a
dr-xr-xr-x+ 1 roaima roaima 0 Jan  7 10:01 a/b
dr-xr-xr-x+ 1 roaima roaima 0 Jan  7 10:01 a/b/c

항상 그렇듯이 이 함수는 다음 위치에 있는 실행 가능한 스크립트에 독립적으로 배치될 수 있습니다 $PATH.

#!/bin/bash
mkdirs()
{
    ...as above...
}

mkdirs "$@"

답변2

중간 디렉터리 생성 시 설정한 모드가 mkdir적용되지 않는 것 같습니다 . -m그러나 적어도 대부분의 경우 를 umask사용하여 설정한 권한을 수정할 수 있습니다.

작품 umask:변제권한 비트는 다음과 같습니다.놓다예를 들어 중개자에게 권한을 부여하려면 umask 0700를 umask로 설정하세요 0077. 여기서는 umask 변경 사항을 포함하기 위해 하위 쉘이 사용됩니다.

$ ( umask 0077; mkdir -p a/b )
$ ls -ld a
drwx------ 3 ilkkachu ilkkachu 4096 Jan  7 07:23 a/
$ ls -ld a/b
drwx------ 2 ilkkachu ilkkachu 4096 Jan  7 07:23 a/b/

마찬가지로 권한을 얻으려면 0555umask를 0222. 그러나 이는 실제로 중개자에게는 작동하지 않으며 권한을 사용하여 생성됩니다 0755. 즉, 속한 사용자의 쓰기 권한을 높입니다.

POSIX 지정중간 경로 이름 구성요소에 대한 권한(옵션 아래 참조 -p):

[...] mkdir 유틸리티는 기존 디렉터리의 이름을 지정하지 않는 dir의 경로 접두사의 경로 이름 구성 요소를 생성해야 하며[누락된 디렉터리 생성과 동일] chmod()다음 인수를 사용하여 함수를 호출해야 합니다. [...]

 2. (S_IWUSR|S_IXUSR|~filemask)&0777모드 매개변수의 값으로, filemask프로세스에 대한 파일 모드 생성 마스크는 어디에 있습니까?

( S_IWUSR그리고 S_IXUSR이러한 권한 비트에 대한 C 상수입니다.)

이것GNU coreutils 온라인 매뉴얼에 따르면:

-p, --parents
파일 권한 비트를 로 설정하여 각 인수에 대해 누락된 상위 디렉터리를 생성합니다. =rwx,u+wx즉, 수정된 umask 를 사용합니다 u+wx. 기존 상위 디렉토리는 무시되고 해당 파일 권한 비트는 변경되지 않습니다.

-m이 옵션은 여기에 적용되지 않지만 umask를 사용하여 해당 옵션에 대한 권한을 제어할 수 있다고 계속해서 설명합니다 .

(텍스트가 올바르지 않은 것처럼 보이지만 "umask는 u=wx작동하려면 이 메서드를 포함해야 합니다"라고 언급하는데, 이는 umask의 반대 의미가 누락된 것 같습니다.)


아마도 mkdir이 작업을 수행하는 이유는 그렇지 않으면 쓰기 권한 없이는 방금 생성한 디렉토리 내에 다음 디렉토리를 생성할 수 없기 때문입니다. x같은 이유로 access/search() 권한 비트에서도 같은 일이 발생합니다.

따라서 쓰기나 검색이 불가능한 디렉터리를 생성하려는 경우 chmod나중에만 생성할 수 있는 것처럼 보입니다. 그렇지 않으면 설정이 umask작동합니다 mkdir.

답변3

다음 명령을 사용할 수 있습니다 install(80년대 BSD의 비표준 명령, GNU coreutils에도 포함됨):

install -m 555 -d a/b/c a/b a

또는 csh-style 중괄호 확장을 지원하는 쉘을 사용하십시오.

install -m 555 -d a{/b{/c,},}

디렉터리 구성 요소가 미리 존재하는 경우 해당 권한(심볼릭 링크를 가리키는 디렉터리의 권한)은 다음과 같습니다.변경됨0555로.

새로 생성된 디렉터리 구성 요소의 권한만 변경하려면 해당 구성 요소를 함수로 실행할 수 있습니다. 예를 들면 다음과 같습니다 zsh.

mkdirhierperm() {
  local mode=$1 dir=$2 dirs=()
  until [[ -d $dir ]] dirs[1,0]=$dir dir=$dir:h
  if (( $#dirs == 0 )); then
    (umask 77 && mkdir -p -- $dirs[-1]) &&
      chmod -- $mode $dirs
  fi
}

mkdirhierperm 555 a/b/c
mkdirhierperm 555 /full/path/to/some/new/dir

답변4

이 작업은 두 단계로 수행할 수 있습니다. 먼저 mkdir디렉터리 생성을 호출한 다음 실행하여 find . -type d -exec chmod 555 {} \;스키마를 수정합니다.

관련 정보