stdin은 단말기가 아니기 때문에 의사 단말기는 할당되지 않습니다.
리모트 서버에 디렉토리를 작성하고 scp를 사용하여 로컬머신에서 리모트로 파일을 복사하는 셸 스크립트를 작성하려고 합니다.지금까지의 내용은 다음과 같습니다.
ssh -t user@server<<EOT
DEP_ROOT='/home/matthewr/releases'
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR=$DEP_ROOT"/"$datestamp
if [ ! -d "$DEP_ROOT" ]; then
echo "creating the root directory"
mkdir $DEP_ROOT
fi
mkdir $REL_DIR
exit
EOT
scp ./dir1 user@server:$REL_DIR
scp ./dir2 user@server:$REL_DIR
실행할 때마다 다음 메시지가 나타납니다.
Pseudo-terminal will not be allocated because stdin is not a terminal.
그리고 그 대본은 영원히 지워지지 않아.
공용 키는 서버에서 신뢰할 수 있으며 스크립트 외부에서 모든 명령을 정상적으로 실행할 수 있습니다.좋은 생각 있어요?
★★를 해 보세요.ssh -t -t
(오류)ssh -tt
합니다.
다음 항목도 참조하십시오.bash 스크립트로 실행된 SSH 세션을 종료하는 중
ssh manpage에서:
-T Disable pseudo-tty allocation.
-t Force pseudo-tty allocation. This can be used to execute arbitrary
screen-based programs on a remote machine, which can be very useful,
e.g. when implementing menu services. Multiple -t options force tty
allocation, even if ssh has no local tty.
' ' '도 '-T
매뉴얼에서
유사 TTY 할당 사용 안 함
Zanco의 답변에 따르면, 당신은 원격 명령을 제공하는 것이 아닙니다.ssh
셸이 명령줄을 해석하는 방법을 나타냅니다.하려면 , 의 합니다.ssh
명령어 호출을 사용하면 리모트명령어가 구문적으로 올바른 여러 줄 문자열로 구성됩니다.
이치노력하다들어 를 파이프로 할 수 에 명령어를 파이프로 연결할 수 있습니다.bash
★★★★★★★★★★★★★★★★★」sh
아마 일 거예요, 가장 은 그냥 하는 가장 간단한 해결책은 단지 결합하는 것입니다.ssh
"CHANGE: "CHANGE MATHANGE:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
상기의 실행은, 다음과 같이 행해 주세요. /bin/bash
.Pseudo-terminal will not be allocated because stdin is not a terminal
또, ., 의, 의, . 、 。EOT
로 둘러싸여 에, 「Single-Parament」는 「Single-Parament」를 참조해 주세요.bash
명령 텍스트가 그대로 전달되도록 로컬 변수 보간 기능을 해제하여 nowdoc으로 인식합니다.ssh
.
파이프의 팬인 경우는, 상기의 내용을 다음과 같이 고쳐 쓸 수 있습니다.
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
대해서도 같은 이 있습니다./bin/bash
상기에 적용됩니다.
하나의 하고 여러 1을 입니다.bash
변수 보간은 다음과 같습니다.
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
위의 솔루션은 다음 방법으로 이 문제를 해결합니다.
ssh user@server
bash에 되며 bash로 됩니다.ssh
.user@server
ssh
"
문자열을 가 "보간된 문자열"로됩니다.이 문자열이 완성되면 인수는 에 전달되는 인수로 구성됩니다.ssh
이 는 '명령어()'로 해석됩니다.ssh
user@server
$(
는 주변합니다.cat
는 뒤에 오는 파일의 내용을 출력하는 명령어입니다.「cat
.<<
맹렬히 공격하다'EOT'
, 세레독의 EOT인 을 지정합니다. 따옴표 " " "'
주변 EOT는 내용이 bash에 의해 보간되지 않고 오히려 리터럴 형식으로 전달되는 특수한 형태의 유전인 nowdoc으로 해석되어야 한다고 지정합니다." " " 에 콘텐츠
<<'EOT'
★★★★★★★★★★★★★★★★★」<newline>EOT<newline>
됩니다.EOT
하는 nowdoc nowdoc으로 .cat
명령어를 입력합니다.cat
interpolated stringnowdoc으로.)
를 종료합니다."
보간 문자열 캡처를 종료합니다.보간된 문자열의 내용은 다음으로 돌아갑니다.ssh
인수로 할 수 .ssh
하여 ''로 합니다.user@server
하는 것을 입니다.cat
두 대신 두 개의 문장이 있는 것도.read
SSH를 사용하다
IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ssh user@server "${SSH_COMMAND}"
같은 에러메시지로 인해 발생했던 관련 문제를 해결했기 때문에 이 답변을 추가합니다.
문제:Windows에서 sygwin을 설치했는데 다음 오류가 발생하였습니다.Pseudo-terminal will not be allocated because stdin is not a terminal
해상도:알고 보니 openssh 클라이언트 프로그램과 유틸리티를 설치하지 않았습니다.그 때문에, sygwin 의 버전이 아니고, ssh 의 Windows 실장을 사용하고 있었습니다.해결책은 openssh cygwin 패키지를 설치하는 것이었습니다.
모든 관련 정보는 기존 답변에 포함되어 있지만, 실용적인 요약을 시도해 보겠습니다.
tl;dr:
DO는 명령줄 인수를 사용하여 실행할 명령을 전달합니다.
ssh jdoe@server '...'
'...'
문자열은 여러 행에 걸쳐 사용할 수 있으므로 여기서 나타내는 문자를 사용하지 않아도 코드를 읽을 수 있습니다.
ssh jdoe@server ' ... '
다음 문서를 사용하는 경우와 같이 명령어를 stdin을 통해 전달하지 마십시오.
ssh jdoe@server <<'EOF' # Do NOT do this ... EOF
명령어를 인수로 전달하면 그대로 기능합니다.
- 유사 단자의 문제는 발생하지 않습니다.
- 명령어 처리 후 세션이 자동으로 종료되므로 명령어 종료 시 스테이트먼트가 필요하지 않습니다.
요컨대 stdin을 통해 명령어를 전달하는 메커니즘은ssh
님의 설계로 인해 회피해야 할 문제가 발생하고 있습니다.
더 알고 싶다면 계속 읽어보세요.
옵션 배경 정보:
타겟 서버에서 실행하는 명령어를 받아들이는 메커니즘은 명령줄 인수입니다.최종 오퍼랜드(non-option 인수)는 1개 이상의 셸 명령어를 포함하는 문자열을 받아들입니다ssh
.
디폴트로는 이들 명령어는 (의사) 단말기를 사용하지 않고 비인터랙티브셸 내에서 무인실행되며(옵션은 암묵적) 마지막 명령어 처리가 완료되면 세션이 자동으로 종료됩니다.
인터랙티브프롬프트에 대한 응답 등 사용자 조작이 필요한 명령어가 있는 경우 리모트세션과의 상호작용을 가능하게 하는 의사 단말기 pty(의사)의 작성을 명시적으로 요구할 수 있습니다.
-t
★★★★ssh -t jdoe@server 'read -p "Enter something: "; echo "Entered: [$REPLY]"'
한 「」는,
read
에 "pty"는 "pty"로 동작합니다.-t
옵션이 필요합니다.pty를 사용하면 stdout과 stderr이 결합되어 stdout을 통해 둘 다 보고됩니다.즉, 일반 출력과 오류 출력의 구별이 없어집니다.예를 들어 다음과 같습니다.
ssh jdoe@server 'echo out; echo err >&2' # OK - stdout and stderr separate
ssh -t jdoe@server 'echo out; echo err >&2' # !! stdout + stderr -> stdout
이 인수가 없는 경우,는 stdin을 통해 명령어를 송신하는 경우를 포함하여 인터랙티브셸을 만듭니다.이것이 문제의 발단이 됩니다.
인터랙티브 쉘의 경우
ssh
는 통상 디폴트로 pty(표준 단말)를 할당합니다.단, 그 stdin이 (실제) 단말기에 접속되어 있지 않은 경우는 제외합니다.stdin 경유로 명령어를 송신하는 것은 의 stdin이 단말기에 접속되어 있지 않기 때문에 pty가 작성되지 않으며 이에 따라 경고가 표시됩니다.
Pseudo-terminal will not be allocated because stdin is not a terminal.
이 경우 pty 작성을 요청하는 것을 목적으로 하는 옵션도 충분하지 않습니다.같은 경고가 표시됩니다.
조금 이상하게도 pty를 강제로 작성하려면 옵션을 두 배로 해야 합니다.
ssh -t -t ...
★★★★★★★★★★★★★★★★★」ssh -tt ...
네가 정말 진심이라는 걸 보여주지아마도 이 매우 신중한 단계를 요구하는 이유는 일이 예상대로 작동하지 않을 수 있기 때문일 것이다.예를 들어, macOS 10.12에서는 위의 명령어와 외관상 동등하며 stdin을 통해 명령어를 제공하고,
-tt
는 정상적으로 동작하지 않습니다.에 응답한 후 세션이 정지합니다.read
★★★★★★★★★★★★★★★★★★:
ssh -tt jdoe@server <<<'read -p "Enter something: "; echo "Entered: [$REPLY]"'
긴 )getconf ARG_MAX
- 이 문서를 참조해 주세요.먼저 스크립트 형식으로 리모트시스템에 코드를 카피하는 것을 검토해 주세요(예를 들어,scp
명령어를 전송하여 스크립트를 실행합니다.
경우, 하세요.-T
stdin을 통해 명령어를 입력합니다.exit
한 경우, 「」, 「」를 해 주세요.-tt
-T
이치노
메시지 " " "Pseudo-terminal will not be allocated because stdin is not a terminal.
입니다.ssh
은 여기서 stdin에서 됩니다.로 ssh
는 처음에 인터랙티브로그인 세션(리모트호스트상의 pty 할당이 필요)을 상정하고 있습니다만, 그 후 로컬 stdin이 tty/pty가 아님을 인식할 필요가 있습니다.ssh
에는 보통, 「stdin」등)./bin/sh
됩니다.ssh
이 경우 디폴트로는 리모트호스트에 pty가 할당되지 않습니다.
를 통해 ssh
의 (ttty/pty 등가:vim
★★★★★★★★★★★★★★★★★」top
의 개요-t
로로로 ssh
사용하다, 사용하다ssh -T user@server <<EOT ...
★★★★★★★★★★★★★★★★★」ssh user@server /bin/bash <<EOT ...
그러면 경고는 사라질 겁니다.
if<<EOF
는, 싱글이 「스케이프」또는 「싱글<<\EOT
★★★★★★★★★★★★★★★★★」<<'EOT'
된 후 ssh ...
그 결과 이 문서 내의 변수는 리모트셸에만 정의되어 있기 때문에 비어 있습니다.
만약에 '만약에'가$REL_DIR
되어 있어야 .$REL_DIR
는 이 .ssh
명령어(아래 버전1) 또는<<\EOT
★★★★★★★★★★★★★★★★★」<<'EOT'
의 됩니다.ssh
는 「어느 쪽인가」에 할 수 .REL_DIR
" " 의 한 ssh
는 stdout에 의해 된다.echo "$REL_DIR"
(아래 버전 2)에 기재되어 있습니다.
이후 이 입니다.ssh -t user@server "$heredoc"
(아래 버전 3)
마지막으로 리모트호스트의 디렉토리가 정상적으로 작성되었는지 확인하는 것도 나쁘지 않습니다(「sh」를 사용하는 리모트호스트에 파일이 존재하는지 확인」을 참조).
# version 1
unset DEP_ROOT REL_DIR
DEP_ROOT='/tmp'
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR="${DEP_ROOT}/${datestamp}"
ssh localhost /bin/bash <<EOF
if [ ! -d "$DEP_ROOT" ] && [ ! -e "$DEP_ROOT" ]; then
echo "creating the root directory" 1>&2
mkdir "$DEP_ROOT"
fi
mkdir "$REL_DIR"
#echo "$REL_DIR"
exit
EOF
scp -r ./dir1 user@server:"$REL_DIR"
scp -r ./dir2 user@server:"$REL_DIR"
# version 2
REL_DIR="$(
ssh localhost /bin/bash <<\EOF
DEP_ROOT='/tmp'
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR="${DEP_ROOT}/${datestamp}"
if [ ! -d "$DEP_ROOT" ] && [ ! -e "$DEP_ROOT" ]; then
echo "creating the root directory" 1>&2
mkdir "$DEP_ROOT"
fi
mkdir "$REL_DIR"
echo "$REL_DIR"
exit
EOF
)"
scp -r ./dir1 user@server:"$REL_DIR"
scp -r ./dir2 user@server:"$REL_DIR"
# version 3
heredoc="$(cat <<'EOF'
# -onlcr: prevent the terminal from converting bare line feeds to carriage return/line feed pairs
stty -echo -onlcr
DEP_ROOT='/tmp'
datestamp="$(date +%Y%m%d%H%M%S)"
REL_DIR="${DEP_ROOT}/${datestamp}"
if [ ! -d "$DEP_ROOT" ] && [ ! -e "$DEP_ROOT" ]; then
echo "creating the root directory" 1>&2
mkdir "$DEP_ROOT"
fi
mkdir "$REL_DIR"
echo "$REL_DIR"
stty echo onlcr
exit
EOF
)"
REL_DIR="$(ssh -t localhost "$heredoc")"
scp -r ./dir1 user@server:"$REL_DIR"
scp -r ./dir2 user@server:"$REL_DIR"
행의 원인은 알 수 없지만 명령어를 인터랙티브한 ssh로 리다이렉트(또는 파이핑)하는 것은 일반적으로 문제의 원인입니다.command-to-run-as-a-last-argument 스타일을 사용하여 ssh 명령줄에서 스크립트를 전달하는 것이 보다 견고합니다.
ssh user@server 'DEP_ROOT="/home/matthewr/releases"
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR=$DEP_ROOT"/"$datestamp
if [ ! -d "$DEP_ROOT" ]; then
echo "creating the root directory"
mkdir $DEP_ROOT
fi
mkdir $REL_DIR'
자이언트)'
- intercredited multiline " " " " ) 。
는, 「의사 단말」의 「의사 단말」의 「 단말기는 「의사 단말」입니다.-t
리모트 머신상에서 동작하는 환경을, 리모트 머신상에서 동작하는 프로그램의 실제의 단말기로서 인식하도록 ssh를 요구합니다.SSH 클라이언트는 그 자체의 표준 입력이 단말기가 아니기 때문에 리모트머신에서 로컬엔드의 실제 단말기에 특별한 단말기 API를 전달할 방법이 없기 때문에 이를 거부하고 있습니다.
당신은 무엇으로 달성하려고 했습니까?-t
★★★★★★★★★★★★★★★★★?
이 답변들을 많이 읽고 그 결과 얻은 해결책을 공유해야겠다고 생각했습니다. 은 ★★★★★★★★★★/bin/bash
유전자가 나오기 전에 더 이상 오류가 나지 않습니다.
사용방법:
ssh user@machine /bin/bash <<'ENDSSH'
hostname
ENDSSH
대신 (오류 발생):
ssh user@machine <<'ENDSSH'
hostname
ENDSSH
또는 다음을 사용합니다.
ssh user@machine /bin/bash < run-command.sh
대신 (오류 발생):
ssh user@machine < run-command.sh
추가:
리모트 인터랙티브프롬프트가 필요한 경우(예를 들어 리모트 실행 중인 스크립트에서 패스워드나 기타 정보를 입력하도록 요구하는 경우)는 이전 솔루션에서는 프롬프트에 입력할 수 없기 때문입니다.
ssh -t user@machine "$(<run-command.sh)"
, 는, 「」logfile.log
:
ssh -t user@machine "$(<run-command.sh)" | tee -a logfile.log
Windows에서 emacs 24.5.1을 사용하여 /ssh:user@host를 통해 일부 회사 서버에 접속할 때 동일한 오류가 발생했습니다.문제를 해결한 것은 "tramp-default-method" 변수를 "plink"로 설정하고 서버에 연결할 때마다 ssh 프로토콜을 실행하는 것이었습니다.PuTTY의 플링크가 필요해요.exe 를 인스톨 해 주세요.
솔루션
- M-x customize-variable (다음 Enter 키를 누릅니다)
- tramp-default-method (다시 Enter 키를 누릅니다)
- 텍스트 필드에 plink를 입력한 후 Apply and Save the buffer를 입력합니다.
- 리모트 서버에 액세스 하려고 하면, C-x-f /user@host: 를 사용하고, 패스워드를 입력합니다.이것으로, Windows 의 Emacs 로 리모트 서버에의 접속이 올바르게 확립되었습니다.
언급URL : https://stackoverflow.com/questions/7114990/pseudo-terminal-will-not-be-allocated-because-stdin-is-not-a-terminal
'programing' 카테고리의 다른 글
Windows 콘솔에서 cURL 명령 실행 (0) | 2023.04.14 |
---|---|
IndexError: 배열에 대한 인덱스가 너무 많습니다. (0) | 2023.04.14 |
깜박임 - 줄임표 삽입 또는 페이드와 같이 오버플로우 시 텍스트를 줄 바꿈 (0) | 2023.04.14 |
iOS Universal Link가 앱 내에서 열리지 않습니다. (0) | 2023.04.14 |
오브젝트 [INFORMATION_SCHEMA]에 대한 해결되지 않은 참조.[표] (0) | 2023.04.14 |