파일에 대한 쓰기 액세스를 비 침습적으로 테스트하는 방법은 무엇입니까?


20

쉘 스크립트에서 실제로 파일을 수정하지 않고 파일에 대한 쓰기 액세스를 쉽고 비 침습적으로 테스트 하는 방법은 무엇입니까?

의 출력을 구문 분석 할 수는 stat있지만 구현과 시간에 따라 통계 출력이 얼마나 다른지 확실하지 않지만 실제로는 복잡하고 취하기 쉽습니다.

파일 끝에 추가하여 성공 여부를 알 수 있지만 다음과 같은 두 가지 이유로 인해 위험 할 수 있습니다.

  1. 이제 추가를 제거해야하며 다른 프로세스가 파일에 쓰는 경우 내 줄이 더 이상 마지막 줄이 아니기 때문에 즉시 중요하지 않습니다.
  2. 파일을 읽는 모든 프로세스는 해당 파일의 내용에 대한 임의의 요구 사항을 가질 수 있으며 해당 응용 프로그램을 중단했을 수 있습니다.

답변:


29

utillity 의- w플래그를 사용하십시오 test.

[ -w /path/to/file ] && echo "writeable" || echo "write permission denied"

나중에 파일에 쓰려고해도 파일에 쓰지 못할 수도 있습니다. 파일이 이동했거나 권한이 변경되었을 수 있습니다. -w쓰기 권한감지하지만 파일을 쓸 수 없도록하기 위해 다른 요인이 개입 될 수도 있습니다 .


1
당연하지! 테스트 매뉴얼 페이지를 확인하려고 생각 했어야합니다. 고맙습니다.
user50849

1
이 쉘 내장입니다 @qweilun,하지만 당신은을 통해 매뉴얼 페이지를 표시 할 수 있습니다 man test또는man [
혼돈

5
@chaos 그것은 쉘 내장 및 외부 실행 파일입니다-시도type -a
Volker Siegel

1
소스 별test 사용 euidaccess간단히 허가 비트를 체크한다 . 쓰기 액세스를 금지 할 수있는 다른 요소 (예 : SELinux)가 없습니까?
zamnuts

2
@BroSlow, &&||같은 우선 순위를 갖는다. 그들은 왼쪽에서 오른쪽으로 평가됩니다.
와일드 카드

11

다른 접근법 :

if >> /path/to/file
then
    echo "writeable"
else
    echo "write permission denied"
fi

이것은 추가를 위해 파일을 열려고 시도하고, 성공하면 파일에 대한 출력으로 명령을 실행 하지 않습니다 (예 : 널 명령 실행 ). 

빈 파일이 존재하지 않으면 빈 파일이 생성됩니다.

명령 의 -w운영자는 test단지 a를 수행 한 stat 다음 액세스 권한이 있어야하는지 여부를 알아 봅니다. 내 대안 (위)은 test일부 특수 조건에서 접근 방식 보다 신뢰성이 높습니다. 왜냐하면 액세스 체크가 쉘이 아닌 커널에 의해 수행되기 때문입니다. 예를 들어

  • 파일이 비 유닉스 파일 시스템에있는 경우 (특히 비 유닉스 파일 서버에서 원격으로 마운트 된 경우 stat) 오해의 소지가있는 모드 값을 반환 할 수 있기 때문 입니다.
  • 파일이 읽기 전용으로 마운트 된 파일 시스템에있는 경우
  • 파일에 ACL이 있고 모드에서 액세스 권한이 있어야하는 것처럼 보이지만 ACL은 파일을 거부하거나 그 반대입니다.
  • 일부 보안 프레임 워크 (AppArmor, SELinux,…)가 파일에 대한 액세스를 거부하는 경우

3
방금 이것을 (데비안에서) 테스트했습니다. 어느 시간도 바뀌지 않았으며 이것이 모든 유닉스에서 작동하는 방식입니다. 액세스 시간은 파일을 읽는 경우에만 업데이트해야하며 수정 시간은 파일에 쓰는 경우에만 업데이트되어야합니다. 이 코드는 없습니다. @ Schwern : 당신은 당신의 진술에 대한 참조가 있습니까? 당신은 그것을 시도한 적이 있습니까?
G-Man, 'Reinstate

2
PS @muru : 방금 touch소유 한 파일을 쓰려고했으나 쓰기 권한이 없었으며 성공했습니다. 나는 그것이 chmod파일이고 추측한다 chmod. 따라서 touch질문에 대한 답변으로 절대 쓸모없는 것으로 보입니다.
G-Man, 'Reinstate

2
@ G-Man 아, 흥미 롭습니다. IIRC vim는 읽기 전용 파일에 강제로 쓸 때 권한을 빠르게 변경하는 동작을합니다. 나는 함께 확인 strace, touch의는 open실패 EACCES하지만 후속 호출에 utimensat내가 생각하는 이유입니다, 성공 touch성공적으로 전체 종료에.
muru

2
@muru : 확인해 주셔서 감사합니다. utimensat(2)"말한다 : 권한 요구 사항 ... 1. 쓰기 액세스 (또는) 2. 호출자의 유효 사용자 ID가 파일의 소유자와 일치해야합니다."
G-남자 '분석 재개 모니카'말한다

3
Champignac과 같은 다른 문제 >> file는 이식성이 없습니다 (예 : zsh에서 NULLCMD를 실행) true >> file. 대신 사용하십시오. 그리고 파일이 명명 된 파이프라면 부작용이 심합니다.
Stéphane Chazelas

3

G-man이 옳다 : 항상 진실을 말하지 [ -w ]는 않는다 . 존재하지 않는 파일과 쉘의 Permission denied 메시지 에 대처하려면 다음을 수행하십시오 .

( [ -e /path/to/file ] && >> /path/to/file ) 2> /dev/null && 
  echo writable || 
  echo not writable

업데이트 : 무서운 것처럼 보이지 않습니까? 글쎄. 흠 ... 어떻게 말해야하는지 ... 이것은 사용하지 말아라. Stephane의 의견을 참조하십시오.

그렇다면 무엇을 결론을 내립니까? [ -w ]진실을 말하지 않더라도 그것은 직무를 수행 하기위한 하나의 명령입니다 . 그렇지 않은 경우, 우리는 그것을 비난하고 버그 보고서를 작성하며 앞으로 작동 할 것입니다. 작동 조건을보다 잘 점검하고 사용하십시오 [ -w ]. 특별한 경우를위한 특별한 코드를 작성하십시오. 해결 방법은 자체 조건이 있습니다.

[ -w /path/to/file ]

선험 이 최고 입니다.


3
파일이 명명 된 파이프 인 경우 읽지 않으면 중단되며 독자가 있어도 부작용이 발생합니다. test -w대부분의 구현에서는 사용 access(2)권한을 테스트하기에 충분해야합니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.