[ Directory Access ]
디렉토리 트리에서의 이동
chdir 함수는 현재 디렉토리로 설정될 디렉토리 이름을 인수로 받는다
-> chdir(“/etc”) || die “cannot cd to /etc ($!)”;
* 괄호는 생략 가능하다
-> print “where do you want to go?”;
chomp($where = <STDIN>);
if (chdir $where) {
# 디렉토리를 옮겼음
} else {
# 디렉토리를 옮기지 못했음
}
l 현재 어느 디렉토리에 있는지 알 기 위해서는 pwd 명령어를 실행해야 한다
l Perl 프로그램이 디렉토리를 바꾼다 하더라도 그 Perl 프로세스를 실행한 부모 프로세스에는 아무 영향도 미치지 않는다
l 마찬가지로 Perl 프로그램이 생성한 프로세스는 Perl 프로그램의 현재 디렉토리에 영향을 미칠 수 없다
l chdir을 인수 없이 사용할 경우 홈 디렉토리를 디폴트로 받는다
글로빙
인수의 확장을 글로빙이라고 하며, perl에서 글로빙은 각괄호 사이에 글로빙 패턴을 두거나, glob함수를 통해서 이루어진다.
-> @a = </etc/host*>
@a = glob(“/etc/host*);
glob함수는 리스트 구문에서 패턴과 일치하는 모든 이름의 리스트를 리턴하거나, 일치하지 않을 경우 공백 리스트를 리턴한다. 스칼라 구문에서는 일치하는 다음번 이름을 리턴하거나, 더 이상 일치하는 것이 없을 경우 undef를 리턴한다.
-> while (defined($nextname = </etc/host*>)) { # 한번에 이름 하나씩 보기
print “one of the files is $nextname ”;
}
-> while ($nextname = </etc/host*>) { # 마지막 이름 부분만을 원할 때
$nextname =~ s#.*/##; # 마지막 슬래쉬 앞 부분을 제거
print “one of the files is $nextname ”;
}
l 파일 글로브 인수 내에는 복수개의 패턴이 허용된다
l 글로브는 동일한 인수의 대등한 echo 명령어가 리턴하는 것과 같은 값들을 리턴한다
디렉토리 핸들
운영체제가 readdir 라이브러리 함수 또는 동등한 것을 제공하면, perl은 디렉토리 핸들을 이용하여 그 루틴에 대한 엑세스를 제공한다.
l 디렉토리 핸들은 특정 디렉토리로의 연결을 나타내며, 디렉토리 내에 있는 파일 이름의 리스트를 읽는데 사용한다.
l 디렉토리 핸들은 항상 읽기 전용으로 열린다
l 디렉토리 핸들을 파일이름을 바꾸거나 파일을 지우기 위해 사용할 수 없다
opendir 디렉토리 핸들을 연다
-> opendir(ETC, “/etc”) || die “Cannot opendir /etc: $!”;
closedir 디렉토리 핸들을 닫는다
-> closedir(ETC);
* 디렉토리 핸들은 그들이 다시 열리거나 프로그램이 끝나기 전에 자동으로 닫힌다
readdir 단일 인수로 디렉토리 핸들을 받아 파일이름을 리턴한다
-> opendir(ETC, “/etc”) || die “no etc?: $!”;
while ($name = readdir(ETC)) { # 스칼라 구문, 루프당 하나
print “$name ”; # ., .., passwd, group등을 출력
}
closedir(ETC);
-> operndir(ETC, “/etc”) || die “no etc?: $!”; # 알파벳 순서로 파일이름 얻기
foreach $name (sort readdir(ETC)) { # 리스트 구문, 정렬됨
print “$name ”; # ., .., passwd, group등을 출력
}
closedir(ETC);
[ 파일과 디렉토리 조작 ]
파일제거
unlink() 함수는 어떤 파일에 대한 이름을 삭제한다
* 파일에 대한 마지막 이름이 삭제되고 그것을 열고 있는 프로세스가 없으면, 그 파일 자체는 제거된다. 파일은 일반적으로 하나의 이름을 가지므로 대부분의 경우 이름을 제거하는 것을 해당 파일을 제거하는 것으로 생각할 수 있다
-> unlink (“fred”); # fred에게 작별인사를
-> print “what file do you want to delete?”;
chomp($name = <STDIN>);
unlink ($name);
-> unlink (“cowbird”, “starling”); # 한번에 두 마리 새를 명중
unlink <*.o>; # 쉘에서의 “rm *.0”와 동일
* unlink의 리턴값은 성공적으로 삭제된 파일의 수이다. 어떤 삭제가 성공했는지 알기 위해서는
한번에 하나씩 해야만 한다.
-> foreach $file (<*.o>) { # .o 파일의 리스트를 하나하나씩
unlink($file) || warn “having trouble deleting $file: $!”;
}
* unlink 함수에 아무런 인수가 주어지지 않으면 $_ 변수가 다시 디폴트로서 사용된다.
파일 이름 변경
rename($old, $new)함수는 UNIX쉘에서 mv 명령과 같은 기능을 한다
-> rename(“fred”, “barney”) || die “Can’t rename fred to barneys: $!”;
l rename은 성공하면 참 값을 리턴하므로, 보통 이 결과를 테스트한다
l Perl에서는 명시적으로 새 디렉토리 내에서 파일의 이름까지 지정해 주어야 한다
-> rename(“file”, “some-directory/file”); # mv file some-directory 와 같다
l mv 명령어는 파일을 한 장치에서 다른장치에 있는 것으로 이름을 변경할 때 그 파일을 복사하지만, rename은 다른 방법으로 옮겨야 함을 나타내는 에러를 얻는다
l File::Find 모듈은 move 함수를 지원한다
링킹(linking)
한 파일이 여러가지 이름으로 필요할 경우 그 파일에 대한 다른 이름을 만드는 연산을 링킹이라고 부른다. 하드링크와 소프트링크 두가지 방법이 있다.
l 하드링크는 그 파일에 대한 원래 이름과 구분이 불가능하다
l OS는 하드링크 참조의 계수(count)를 유지하며, 파일이 생성 됐을 때 하나의 링크로 시작해서 하드링크가 늘어나면 계수가 증가하고, 제거되면 계수가 감소한다. 마지막 링크가 사라지고 그 파일이 닫히면 파일은 없어진다
l 파일로의 모든 하드링크는 반드시 같은 마운트 파일 시스템상에 있어야만 한다. 그러므로 한 파일에 대한 새로운 하드링크를 다른 곳에 마운트된 파일 시스템에 만들 수 없다
l 하드링크는 디렉토리에 대해서 제한되며, 디렉토리 구조를 트리로 유지하기 위해 디렉토리 루트에는 그 자신에 대한 점(.)파일 링크와 서브디렉토리에서의 일련의 점점(..) 하드링크만을 허용한다.
l 심볼릭링크는 경로명을 데이터로 담고 있는 파일이다
l 심볼릭링크는 반드시 존재하는 파일 또는 디렉토리에 대한 참조일 필요는 없다
l 최대 8단계의 심볼릭링크가 허용된다
l 하드링크는 해당파일의 이름을 하나하나 헤아림으로써 파일의 내용물을 잃지 않도록 보호하지만 심볼릭링크는 그 내용물이 사라지는 것을 막지 않는다
l 하드링크는 다른 곳에 마운트 된 파일 시스템에는 불가능하지만 심볼릭링크는 가능하다
l 심볼릭링크만이 디렉토리에 대해서도 만들어 질 수 있다
링크 생성
link() 함수는 이전 파일이름과 그 파일에 대한 새로운 이름의 두 인수를 받아 하드링크를 만든다
-> link(“fred”, “bigdumbguy”) || die “cannot link fred to bigdumbguy”;
# UNIX 쉘에서 ln fred bigdumbguy 와 같다
symlink() 함수는 심볼릭 링크를 생성한다
-> symlink(“barney”, “neighbor”) || die “cannot symlink to neighbor”;
# UNIX 쉘에서 ln –s barney neighbor 와 같다
readlink() 함수는 지정된 심볼릭링크가 가리키는 이름을 리턴한다
-> if (defined($x = readlink(“neighbor”))) {
print “neighbor points at ‘$x’ ”;
} # UNIX 쉘에서 ls –l neighbor 와 비슷하게 동작한다
디렉토리 생성과 제거
mkdir() 함수는 새로운 디렉토리 이름과 생성된 디렉토리 허가권의 모드를 받는다
-> mkdir(“gravelpit”, 0777) || die “cannot mkdir gravelpit: $!”;
# UNIX 쉘에서 mkdir gravelpit 과 비슷하다
l 모드를 0777로 하면 모든 것이 동작한다
l 허가권에 대해선 UNIX에서 chmod와 umask 를 참조 할 것
rmdir() 함수는 빈 디렉토리를 제거한다
-> rmdir(“gravelpit”) || die “cannot rmdir gravelpit: $!”;
# UNIX 쉘에서 rmdir gravelpit 과 같다
허가권(permission) 변경
chmod() 함수로 허가권 변경을 한다
-> chmod(0666, “fred”, “barney”);
# fred와 barney를 누구나가 읽고 쓸수 있게 만듦
l 첫번째 인수로 8진수 모드를 받는다
l 리턴값은 성공적으로 조정된 파일의 수이므로, unlink처럼 동작하며, 에러검사에 활용이 가능하다
-> foreach $file (“fred”, “barney”) {
unless chmod (0666, $file) {
warn “hmm.. couldn’t chmod $file: $!”;
}
}
소유권(ownership) 변경
파일 시스템에서 모든 파일은 하나의 소유자와 그룹을 가지며, 파일의 소유자와 그룹은 다른 누구에게 소유자와 그룹 허가권을 적용할지를 결정할 수 있다
chown 함수는 사용자 ID번호(UID), 그룹 ID번호(GID), 그리고 파일 이름의 리스트를 받아서 리스트된 파일 각각의 소유권을 지정된대로 바꾼다
l 성공적으로 변경된 파일의 수가 리턴된다
l 한번에 소유자와 그룹 모두를 변경하며, ID를 변경하지 않으려면 실제 사용자 또는 그룹 ID 대신 –1을 사용한다
-> chown(1234, 35, “slate”, “granite”); # 다음과 동일 (디폴트 그룹 stoners)
# chown fred slate granite
# chgrp stoners slate granite
시간표시 변경
각 파일은 세 개의 시간표시 집합과 연관된다
: 마지막 액세스 시간, 마지막 수정시간, 마지막 inode 수정 시간
utime 함수는 파일이름의 리스트를 받고, 영향을 미친 파일의 수를 리턴한다.
-> $atime = $mtime = 700_000_000; # 얼마전
utime($atime, $mtime, “fred”, “barney”);
time 함수는 현재 시간을 리턴한다
-> $when = time() + 20*60; # 지금부터 20분
utime($when, $when, “max_headroom”);