내 컴퓨터에 (Ruby 버전 관리자)를 설치 했는데 rbenv
다음과 같이 작동합니다.
$ rbenv local
2.3.1
에 쓰기표준 출력내 로컬 버전의 Ruby입니다. 이 버전을 구출하고 다른 경우에 재사용할 수 있도록 변수에 선언하고 싶습니다.
$ declare -r RUBY_DEFINED_VERSION=$(rbenv local)
$ echo Using ruby version $RUBY_DEFINED_VERSION
Using ruby version 2.3.1
효과가있다!
하지만 사용하고 싶지 않아요서브쉘작업을 완료합니다( $()
또는 사용 ``
). 나도 똑같이 사용하고 싶다껍데기나는tmp작업을 완료하는 데 필요한 파일입니다.
이를 수행할 수 있는 방법이 있습니까?
노트: declare -r
필수 사항은 아니며 간단할 수 있습니다 var=FOOBAR
.
답변1
해킹이 있지만 루프를 통해 실행해야 한다면 의미가 있다고 생각합니다.
다음과 같이 열 수 있습니다 cat
coproc
.coproc CAT { cat; }
그러면 cat
백그라운드에서 명령이 실행되고 두 개의 환경 변수( CAT_PID
및 ) 가 설정됩니다 CAT
. 이 변수는 사용된 파일 설명자(파이프)를 (순서대로) 포함 하는 CAT
배열입니다 .STDOUT
STDIN
cat
&${CAT[1]}
따라서 표시되는 모든 항목 에 출력을 쓸 수 STDIN
있으며 내장 명령을 사용하여 read
읽을 변수를 cat으로 설정할 ${CAT[0]}
수 있습니다 STDOUT
.
예는 다음과 같습니다.
coproc CAT { cat; }
echo 123 >&${CAT[1]}
read myvar <&${CAT[0]}
테스트하려면:
echo $myvar
123
사용 후에는 고양이를 차단하는 것을 잊지 마세요. 프로세스를 종료하면 이를 수행할 수 있습니다.
kill $CAT_PID
이는 성능 튜닝에 큰 영향을 미칩니다.
업데이트: 구분된 문자열을 bash
구현했습니다 null
. 그래서 이진 데이터를 다룰 때는 read
정말 까다롭습니다 . 한 번에 한 바이트씩 읽을 수 있으며 null은 변수의 빈 문자열이 LC_ALL=C read -r -n1 -d $'\0'
됩니다 .${REPLY}
답변2
Bash를 사용하면 다음과 같은 작업도 수행할 수 있습니다.
read a < <(echo hello)
echo "$a"
또는 다음과 같습니다:
shopt -s lastpipe
echo hello | read a
shopt -u lastpipe
echo "$a"
하지만 여전히 Ruby를 실행할 하위 프로세스를 시작해야 하므로 무엇을 피하려고 하는지 잘 모르겠습니다...
답변3
Linux에서 bash
5.1(또는 zsh) 이전 버전을 사용하는 경우 다음을 수행할 수 있습니다.
{
chmod u+w /dev/fd/3 # only needed in bash 5.0
rbenv local > /dev/fd/3
IFS= read -rd '' -u 3 variable
} 3<<< ''
비록 숨겨져 있지만 여기에서는 문서별 또는 여기에서는 문자열과 같은 임시 파일을 사용합니다.
bash
5.1 일반 임시 파일 대신 파이프를 사용하십시오(적어도 herefile/herestring의 내용이 파이프 버퍼에 들어갈 만큼 충분히 작은 경우). 이를 사용하면 언제든지 임시 파일을 수동으로 만들 수 있습니다.
tmpfile=$(mktemp) || exit
{
rm -f -- "$tmpfile"
rbenv local >&3
IFS= read -rd '' -u4 variable
} 3> "$tmpfile" 4< "$tmpfile"
<<
<<<
(예 : 쉘이 종료될 때 스크립트가 종료되거나 남겨질 위험을 최소화하려면 tmpfile을 일찍 제거하십시오 ).rbenv
출력이 파이프에 들어갈 수 있는 것보다 적은 데이터(일반적으로 64KiB) 인 경우 rbenv
여전히 Linux 및 Linux에서만 임시 파일 대신 파이프를 사용할 수 있습니다.
{
rbenv local > /dev/fd/3
IFS= read -rd '' -u 3 variable
} 3< <(:)
ksh93
또는 최신 버전 의 경우 mksh
하위 쉘을 시작하지 않는 명령 대체 형식을 사용하십시오.
variable=${
rbenv local
}
이 버전은 현재 bash 및 zsh 개발 버전에서도 사용할 수 있습니다.
이 방법과 달리 IFS= read -rd ''
출력에서 후행 줄 바꿈을 제거합니다(일반 명령 대체와 마찬가지로).
이를 달성하기 위해 ksh93의 현재(2024년 기준) 버전은 내부적으로 사전 삭제된 임시 파일( /dev/shm
내 Debian 시스템에서), mksh( /tmp
내 시스템에서), zsh-dev를 사용하며 파일만 나중에 삭제됩니다. bash-dev를 삭제하고 익명으로 만들기메모리지원되는 곳에는 임시 파일이 있고, 지원되지 않는 곳에는 미리 삭제된 임시 파일이 있습니다 /tmp
.
이전 버전에서는 자동으로 삭제된 임시 파일을 가져오기 위해 프로세스 대체 형식을 zsh
활용했습니다 (여기서는 익명 함수에 대한 매개변수로 전달됨).=(...)
() { rbenv local > $1; IFS= read -rd '' variable <$1; } =()
1 그러나 zsh에 관한 한 ${ cmd }
현재 이 작업을 수행할지 아니면 따옴표 없이만 수행할지에 대한 논쟁이 있습니다.