bash : 읽기 전용 루트 파티션에서 <<<“$ VARIABLE”읽기를 사용할 때의 일부 문제. 알려진 해결 방법이 있습니까?


11

우연의 일치로 ATA-ID-to-device-name 스크립트를 사용해야했습니다 ( /server/244944/linux-ata-errors-translating-to-a-device-name/ 읽기 전용 / 파티션 에서 426561 # 426561 ) . 궁금한 점이 있다면 /파티션에 액세스 할 수있는 우분투 복구 콘솔 이었지만 기본적으로 읽기 전용으로 마운트합니다. 그렇지 않으면 아마도 특정 줄로 인해 R / O 시스템에서 내 스크립트가 이상하게 작동한다는 것을 알지 못했을 것입니다.

IFS=: read HostMain HostMid HostSub <<< "$HostFull"

쓰기 권한이 없으면 작동 하지 않습니다 . 그래도 실패 할 것이라고는 생각하지 않았습니다. 그러나 분명히 <<<운영자 임시 파일을 어딘가에 쓸 필요가 있습니다.

그러나 임시 파일 작성을 피할 수있는 방법이 있습니까, 아니면 파일을 작성할 위치를 지정하는 방법이 있습니까? Ubuntu 복구 콘솔에는 /run디렉토리 에 대한 쓰기 권한이 있습니다. 이상하게도 read임시 파일을 평소가 아닌 다른 곳에 쓰기 위해 "알릴" 수 있습니다.


2
@gniourf_gniourf 아니오,“파일 디스크립터를 여는 것”은 문제가되지 않으며 (왜 그럴까요?), 이것과 관련 /dev/fd이 없습니다. <<<그러나 임시 파일 (어딘가에 작성해야 함)을 작성하기 때문에 범인입니다.
Gilles 'SO- 악마 그만

답변:


8

배열은 임시 파일이 없어도 문자열 구문 분석을 수행 할 수 있습니다. 장갑을 끄는 것을 잊지 마십시오.

set -f
IFS=: Hosts=($HostFull)
HostMain=${Hosts[0]}
HostMid=${Hosts[1]}
HostSub=${Hosts[2]}
set +f

2
또는없는 IFS경우 에도 공백이없는 경우 $HostFull: Hosts=( ${HostFull//:/ } ). 또는 공백이 있어도 HostMain=${HostFull%%:*}; HostMid=${HostFull#*:}; HostSub=${HostMid#*:}; HostMid=${HostMid%:*}(또는 비슷한 것이 혼란스러워집니다 :D).
gniourf_gniourf 23시 33 분

매개 변수 확장이 까다로운 탈취임을 보여 주듯이 당신은 맞습니다 ...
xae

4

@gniourf_gniourf에 동의하는데, 아마도 파일 액세스 권한이 필요하지만 파일 설명자, 대부분 파일에는 액세스 권한이 필요하지 않습니다.

읽기 전용 파티션에있을 때 명령 실행을 추적하여이를 테스트 할 수 있습니다.

{ strace -p "$$" & sleep 1; read var1 <<< "hi"; sleep 1; kill "$1"; }

위의 내용은 straceBash shell (process $$) 에서 실행 됩니다 . 그런 다음 1 초 동안 휴면 상태 read에서 STRING에서 실행합니다 . 문자열 "hi"을이 위치에 넣었습니다 . 그런 다음 sleep에 1 초 이상 다음 killstrace.

이 출력을 구문 분석하는 동안 파일이 파일 O_WRONLY로 쓰기위한로 열린다는 것을 알 수 있습니다.

open("/tmp/sh-thd-4137571604", O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3

위의 명령 순서에 따라 어떤 파일을 쓰고 있는지 볼 수 있습니다.


1
"파일 디스크립터를 작성하지 마십시오"(의미가 없습니다). 생성하려면 파일을 . 그것은 read쓰기 위해 파일을 여는 것이 아니며 (어리석은 것입니다), <<<입니다.
Gilles 'SO- 악마 그만

@ Gilles-고마워, 나는 그것이 무엇을 말하고 있는지 이해하지 못했습니다. A.
slm을

대단히 감사합니다! 비슷한 문제로 미래에 여러 번 도움이 될 수있는 매우 좋은 기술입니다. 그러나 한 가지 입니다 나를 걱정, 그것은 사실이다 /tmpA는 하드 코딩 된 경로. 그리고 아마 당신은 그것을 짐작 한 /tmp IS 이미하지만 읽기 전용뿐만 아니라! 그리고 복구 콘솔에서 작업하면 라이브 파일 시스템에 로그인하게되므로 심볼릭 링크 나 그 어떤 것도 (콘솔에있는 동안조차도) 엉망으로 만들고 싶지 않습니다.
syntaxerror

3

이러한 종류의 작업에 위치 매개 변수가 매우 유용하다는 것을 알았습니다. 일반적으로 모든 쉘에 이식 가능하며 포크 나 임시 파일이 없습니다.

$ HostFull=main:mid:sub    
$ oldIFS=$IFS; IFS=:; set -- $HostFull; IFS=$oldIFS
$ echo $1
main
$ echo $2
mid
$ echo $3
sub

좋은 접근 방식! 감사합니다. 또한 외부 도구가 필요하지 않습니다 (일반적으로 제한된 환경에서는 찾을 수 없음). 유일하게 할 수 있습니다 몇 가지 문제를 일으킬는이 $1, $2, $3물건 : 스크립트에서 그 기억이 일반적으로 스크립트에 전달 된 인수에 설 것 자체 . -그리고 우리가있는 동안 : 만약 IFS가 공백이라면, * IFS = *는이 문법에서하지 않을 것입니다; IFS = ''를 명시 적으로 지정해야합니다 .
syntaxerror
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.