php
이 방법으로 대상 파일에 연결하는 쉘() 스크립트가 있습니다 .
- 파일과 디렉토리가 쓰기 가능한지 확인하십시오
php
(is_writable()
이것이 문제는 아닌 것 같습니다). - 내부 파일 편집 명령을 사용하십시오
sed
.
grep -q "$search" "$passwd_file" && { sed -i "s|$search|$replace|" "$passwd_file"; printf "Password changed!\n"; } || printf "Password not changed!\n"
결과적으로 나는 (다른 모든 것은 정확하지만 myuser:www-data
) myuser:myuser
.
파일 그룹 소유권이 변경 됩니까 sed
? 가능하다면 이를 방지하는 방법은 무엇입니까?
답변1
sed
내부 편집 모드에 작은 문제가 있습니다 -i
. 내부에 임의로 생성된 문자열이 포함된 sed
동일한 디렉터리에 이름이 지정된 임시 파일을 만듭니다 . 이 파일은 원본 파일의 수정된 내용으로 채워집니다. 작업이 완료되면 원본 파일을 삭제하고 임시 파일 이름을 원본 파일 이름으로 변경합니다. 그래서 그건 사실이 아니야sedy08qMA
y08qMA
sed
제자리에서 편집. 호출하는 사용자의 권한과 새 inode 번호를 사용하여 새 파일을 생성합니다. 이 동작은 대부분 양호하지만 예를 들어 하드 링크가 끊어졌습니다.
하지만 원한다면진짜내부 편집의 경우 를 사용해야 합니다 ed
. 임시 파일 없이 표준 입력에서 명령을 읽고 파일을 직접 편집합니다( ed
메모리 버퍼에서 수행됨). 일반적인 방법은 printf
빌드 명령 목록을 사용하는 것입니다.
printf "%s\n" '1,$s/search/replace/g' wq | ed -s file
이 printf
명령은 다음과 같은 출력을 생성합니다.
1,$s/search/replace/g
wq
이 두 줄은 ed
명령입니다. 첫 번째 검색 문자열을 search
로 바꿉니다 replace
. 두 번째는 w
변경 사항을 파일에 쓰고( ) 종료합니다( q
). -s
진단 출력을 억제합니다.
답변2
-i
sed
매개변수는 런타임에 임시 파일을 생성하고 최종적으로 해당 임시 파일로 실제 파일을 덮어쓰는 방식으로 작동합니다 . 임시 파일 소유권이 기본값으로 설정되어 있으므로 이것이 문제의 원인일 가능성이 높습니다.myuser:myuser
상위 디렉터리에 이 비트를 설정 하면 setgid
(상위 디렉터리가 그룹에 속하는 경우에만 www-data
) 이 디렉터리 아래에 생성된 파일이 동일한 그룹을 상속하게 됩니다.
이 작업을 수행할 수 있어야 합니다.
chmod g+s parent-dir-of-your-file
나는 이것이 setgid
드릴 비트의 매우 일반적인 용도라고 생각합니다.
답변3
추가 입력을 파이프해야 한다는 점을 고려하면 대신 사용하는 것이 ed
중복되는 것 같습니다. sed
현재 개발 중인 배포판(CentOS 5.10)에는 해당 옵션과 함께 사용할 때 단순히 이름을 바꾸는 대신 임시 파일 "복사본"을 활용하는 -c
옵션이 있습니다. 이것을 테스트해 보니 인라인으로 편집할 때 원래 소유자와 그룹이 유지되면서 잘 작동합니다. 수정 시간을 보존하지 않습니다.sed
-i
예를 들어,sed -ci -e '3,5d' file.txt
-c
이름을 바꾸는 대신 사본을 사용하십시오(예: 소유권/그룹 유지).-i
인라인 편집-e
실행할 스크립트/표현식
sed
이 옵션이 다른 배포판에서 얼마나 일반적인지는 잘 모르겠습니다 . 솔라리스 10에는 그런 기능이 없지만 솔라리스에는 제가 원하는 것이 많지 않습니다.
답변4
나는 열심히 노력했다https://crates.io/crates/sd문자열만 교체해도 괜찮습니다. 플래그는 수정되지 않습니다.
이를 설치하려면 Rust를 설치한 다음 "cargo install sd"를 설치해야 합니다.
현재 Rust는 아래와 같이 많은 사용 사례에서 C/C++에 대한 실행 가능한 대체 언어입니다. 때때로 더 나은 대안을 얻기 위해 설치를 후회하지 않을 것입니다.