SSH TTY allocation कमांड को कब बदलता है?
SSH TTY allocation प्रॉम्प्ट, स्ट्रीम, सिग्नल और टर्मिनल पहचान बदलता है। जानें कि automation बिगाड़े बिना -T, -t या -tt कब चुनना है।

SSH कमांड में -t जोड़ने से केवल प्रॉम्प्ट दिखाई नहीं देता, बल्कि बहुत कुछ बदलता है। यह तीन अलग रिमोट स्ट्रीम की जगह टर्मिनल लगाता है, टर्मिनल लाइन नियम सक्रिय करता है, सेशन को controlling terminal देता है और प्रोग्राम को ऐसा व्यवहार करने के लिए प्रेरित करता है जैसे कोई व्यक्ति उसे देख रहा हो। इससे interactive sudo रन ठीक हो सकता है, लेकिन parser, pipeline या cancellation चुपचाप टूट सकते हैं।
बिना निगरानी चलने वाले काम में डिफॉल्ट रूप से PTY नहीं होना चाहिए। इसे तभी मांगें जब रिमोट प्रोग्राम को सच में टर्मिनल जैसा व्यवहार चाहिए, और इस चुनाव को कमांड के अनुबंध का हिस्सा मानें। मैंने कई deployment script देखी हैं जिनमें आपात स्थिति के दौरान -tt जोड़ा गया और वह वर्षों तक रहा, जबकि किसी को याद नहीं था कि उसने कौन सी खराबी छिपाई थी।
PTY process environment बदलता है
SSH TTY allocation रिमोट process को मिलने वाले file descriptor बदलता है, केवल output का रूप नहीं। PTY के बिना OpenSSH standard input, standard output और standard error को pipe या socket pair से जोड़ता है। PTY के साथ OpenSSH उसे controlling terminal बनाता है और वही terminal descriptor तीनों standard stream पर लगाता है।
इस implementation detail के साफ दिखाई देने वाले नतीजे हैं। कोई प्रोग्राम isatty() को call करके interactive code path चुन सकता है। Terminal driver विशेष input character संभाल सकता है, input echo कर सकता है, line ending बदल सकता है और foreground process group पर नजर रख सकता है। Standard error का अलग remote channel नहीं रहता, क्योंकि दोनों output descriptor उसी terminal की ओर जाते हैं।
RFC 4254 इन बातों को protocol स्तर पर अलग रखता है। कोई session पहले pty-req मांग सकता है और उसके बाद shell या exec command मांग सकता है। PTY request में terminal type, dimensions और encoded terminal mode होते हैं। यह request किसी exec request को login shell नहीं बनाती।
OpenSSH इस चुनाव के लिए तीन उपयोगी रूप देता है:
ssh -T host commandPTY allocation को साफ तौर पर बंद करता है।ssh -t host commandतब PTY मांगता है जब local client के पास terminal हो।ssh -tt host commandlocal input के pipe या किसी दूसरे nonterminal source से आने पर भी request को force करता है।
दो -t किसी अधिक शक्तिशाली remote terminal का अर्थ नहीं हैं। वे local safety check को override करते हैं। Build runner, agent process या printf ... | ssh में यह फर्क जरूरी है, क्योंकि एक -t “Pseudo-terminal will not be allocated because stdin is not a terminal” दिखाकर उन terminal semantics के बिना आगे चल सकता है जिनकी लेखक को उम्मीद थी।
PTY न होने पर transparent byte path भी बचा रहता है। OpenSSH का ssh(1) manual इस mode को भरोसेमंद binary transfer के लिए सही बताता है। PTY processing rule वाला character device है, इसलिए archive, database dump या ऐसा machine-readable output भेजने के लिए गलत transport है जिसके bytes बिल्कुल समान रहने चाहिए।
यही चुनाव configuration में छिपा हो सकता है। OpenSSH की RequestTTY client setting no, yes, force या auto स्वीकार करती है, जो सामान्यतः -T, -t और default व्यवहार से मिलने वाले विकल्पों के बराबर हैं। Command line पर terminal न मांगने के बावजूद वह मिल रहा हो, तो ssh -G host.example से प्रभावी client configuration देखें। Host block और included file दो एक जैसी दिखने वाली command को अलग session में भेज सकते हैं।
Server की भी भूमिका है। PermitTTY allocation से मना कर सकता है और authorized key entry पर no-pty restriction हो सकती है। Forced command PTY पर तभी चलती है जब client उसे मांगे और server अनुमति दे। मना किए जाने को वास्तविक interface mismatch मानें, और अधिक -t लगाकर retry करने का कारण नहीं।
बदलाव से पहले दोनों mode मापें
SSH option का अनुमान लगाते रहने की तुलना में एक छोटा probe अधिक जानकारी देता है। इसे उसी account, host configuration और command path पर चलाएं जिसका production उपयोग करता है:
probe='
for fd in 0 1 2; do
if test -t "$fd"; then kind=tty; else kind=not-tty; fi
printf "fd%s=%s\n" "$fd" "$kind"
done
printf "term=%s\n" "${TERM-unset}"
printf "stdout-marker\n"
printf "stderr-marker\n" >&2
exit 23
'
ssh -T host.example "$probe" >no-pty.out 2>no-pty.err
printf 'no-pty ssh status=%s\n' "$?"
ssh -tt host.example "$probe" >pty.out 2>pty.err
printf 'pty ssh status=%s\n' "$?"
Nonterminal run को तीन fdN=not-tty line, term=unset और stdout-marker को no-pty.out में लिखना चाहिए। केवल stderr-marker को no-pty.err में जाना चाहिए। सही TERM परिणाम अलग हो सकता है क्योंकि client और server environment setting को अलग ढंग से स्वीकार कर सकते हैं, इसलिए उदाहरण पर निर्भर होने के बजाय अपने असली route का परिणाम दर्ज करें।
PTY run को तीनों descriptor tty के रूप में दिखाने चाहिए। दोनों marker आम तौर पर pty.out में आएंगे, और line ending अक्सर carriage return plus line feed होगी। अगर local SSH diagnostic है तो वह pty.err में आएगा, लेकिन यह remote program के मूल standard error को अलग stream के रूप में वापस नहीं ला सकता। दोनों SSH command को 23 return करना चाहिए, क्योंकि केवल PTY allocation remote exit status को नहीं मिटाता।
Job बदलने से पहले probe में असली executable जोड़ें। command -V tool, pwd, filtered environment print और program के ऐसे diagnostic flag शामिल करें जिनमें secret न हो। Output बदले तो पता करें कि किस observation ने branch बदली: terminal detection, TERM, terminal width, merged stream, startup file या prompt। “-t से चल गया” केवल symptom report है।
Probe को उसी launcher से भी चलाएं। Shell में paste की गई terminal command के पास local TTY होता है, जबकि agent या continuous integration worker के पास अक्सर नहीं होता। इसलिए keyboard पर -t के साथ किया गया test automated run से अलग हो सकता है जब तक आप -tt नहीं जांचते, और forced PTY job को ऐसा input दे सकता है जिसकी उसे उम्मीद नहीं थी।
Input को output से अलग जांचें। ssh -n client के standard input को /dev/null से redirect करता है, और StdinNull setting configuration में यही काम करती है। यह तब उपयोगी है जब remote command को caller का input कभी नहीं पढ़ना चाहिए, लेकिन इससे PTY allocation अपने आप बंद नहीं होता। Null input वाला forced PTY भी terminal detection, stream merging और hangup behavior बदलता है।
SSH को loop के अंदर चलाते समय सावधानी रखें। -n के बिना पहली remote command loop के लिए रखी line पढ़ सकती है, चाहे remote process उन्हें पढ़ना न चाहता हो। PTY के साथ terminal echo उन bytes को transcript में भी लौटा सकता है। Runs के बाकी फर्क समझने से पहले साफ करें कि standard input का मालिक कौन है।
sudo prompt का अनुबंध स्पष्ट होना चाहिए
sudo को authentication का तरीका चाहिए, और PTY उसे password पढ़ने के लिए terminal देता है। sudo manual कहता है कि वह सामान्यतः user के terminal से password पढ़ता है। Terminal के बिना password की जरूरत होने पर command fail होती है, जब तक askpass helper उपलब्ध न हो या caller कोई दूसरा input method न चुने।
यह आम fix को समझाता है:
ssh -t host.example 'sudo systemctl restart example.service'
यह उस इंसान के लिए ठीक है जो password type करके command देखना चाहता है। Unattended execution में यह खराब सुधार है। Job input के लिए हमेशा wait कर सकता है, prompt अपेक्षित output को खराब कर सकता है, और अंततः कोई password को उसी channel में pipe कर सकता है जिसमें command data जा रहा है।
Automation में noninteractive sudo उपयोग करें:
ssh -T host.example \
'sudo -n /usr/bin/systemctl restart example.service'
-n sudo को prompt न करने के लिए कहता है। Cached credential या sudoers policy interaction के बिना action authorize न करे तो sudo error के साथ exit करता है। यह failure उपयोगी है: caller को hidden prompt के बजाय तय status मिलता है। Privileged automation सच में जरूरी हो तो exact command और arguments के लिए सीमित sudoers rule रखें। किसी भी shell को password के बिना चलाने की अनुमति availability problem को बहुत बड़े authority problem में बदल देती है।
Unattended job को cached sudo timestamp पर निर्भर न करें। Cache authentication context से जुड़ा होता है, और terminal तथा session की details policy के अनुसार बदलती हैं। कोई job administrator द्वारा एक मिनट पहले sudo उपयोग करने पर सफल हो और शांत weekend के बाद fail हो, तो उसके पास authorization design नहीं है, केवल timing का संयोग है।
sudo -S standard input से password पढ़ता है। इससे no-PTY command चल सकती है, लेकिन secret data path में मिल जाता है और password handling caller की जिम्मेदारी बनती है। Agent और नियमित automation में इससे बचें। Askpass helper graphical human workflow में काम आ सकता है, लेकिन वह भी interactive authentication है और उसे अचानक unattended job में नहीं जोड़ा जाना चाहिए।
यहां अक्सर दो PTY आपस में मिलाए जाते हैं। SSH sudo शुरू करने से पहले remote PTY allocate कर सकता है। अलग से, आधुनिक sudo I/O logging और isolation के लिए authorized command को अपने PTY में चला सकता है; sudo 1.9.14 में use_pty default रूप से enabled है। जब SSH session के पास terminal नहीं है, तो यह inner PTY outer password prompt उपलब्ध नहीं कराता। यह sudo के पास command चलाने की पर्याप्त जानकारी आने के बाद शुरू होता है।
कुछ sudoers configuration policy के रूप में terminal भी मांगते हैं। पुराने enterprise configuration में requiretty आम था और आज के system में भी बचा हो सकता है। हर “terminal is required” message को password prompt मानने के बजाय प्रभावी sudoers policy जांचें।
PTY shell startup file नहीं चुनता
PTY वाली SSH command अभी भी account के configured shell में -c के साथ चलती है। OpenSSH का sshd(8) manual कहता है कि requested command इसी तरह execute होती है, और server source command को user shell तक भेजता है। PTY allocation shell के आसपास descriptor बदलता है; वह -i, -l या login option नहीं जोड़ता।
यह तब जरूरी है जब PATH, language manager या alias interactive prompt पर हो लेकिन automation में नहीं। -t जोड़ने से path ठीक होता दिख सकता है क्योंकि startup file में terminal test है या called tool terminal detect करता है। हो सकता है इससे कुछ न बदले। इस पर निर्भर job developer द्वारा अपने terminal के लिए बदली गई dotfile से बंध जाती है।
Bash का एक special case इस भ्रम को और कठिन बनाता है। उसका manual कहता है कि interactive login shell profile file पढ़ता है, interactive nonlogin shell .bashrc पढ़ता है और noninteractive shell BASH_ENV उपयोग करता है। Bash यह पहचानने की कोशिश भी करता है कि उसे remote shell daemon ने शुरू किया है और noninteractive होने पर भी .bashrc पढ़ सकता है, जब तक उसे sh नाम से न चलाया गया हो। यह Bash का व्यवहार है, SSH का वादा नहीं, और हर account shell पर लागू नहीं होता।
जरूरत होने पर shell mode को सीधे चुनें:
# A predictable noninteractive Bash command with explicit inputs
ssh -T host.example \
'PATH=/usr/local/bin:/usr/bin:/bin /bin/bash -c '\''command -v deploy && deploy'\'''
# A login environment, requested because the command truly depends on it
ssh -T host.example \
'/bin/bash -lc '\''command -v deploy && deploy'\'''
दूसरा रूप जानबूझकर login startup file पढ़ता है और उनके risk भी अपनाता है: profile का output protocol खराब कर सकता है, और profile बिना deployment review के behavior बदल सकती है। Production job के लिए absolute executable path और छोटा explicit environment आम तौर पर बेहतर हैं।
Alias भी trap है। Noninteractive Bash alias expand नहीं करता जब तक expand_aliases enabled न हो, और shell function तभी मौजूद होता है जब startup mechanism उसे define या import करे। यदि ssh host deploy केवल -t जोड़ने पर काम करता है, तो जांचें कि deploy असली executable है। Remote account program खोज पाएगा या नहीं, यह terminal को तय नहीं करना चाहिए।
याद रखें कि SSH command string भेजता है, final executable के लिए argument vector नहीं। Local shell अपनी quoting process कर चुका होता है, उसके बाद remote account shell string को फिर parse करता है। PTY allocation इन दोनों parse को नहीं बदलता। Value में space या shell metacharacter हो सकते हों तो fixed input वाली script भेजें, तय data format वाला remote helper उपयोग करें या हर layer को सही quote करें। Local shell द्वारा जल्दी expand किए गए argument को terminal ठीक नहीं कर सकता।
Ctrl-C केवल PTY के साथ terminal rule मानता है
PTY के साथ Ctrl-C सामान्यतः input byte है जिसकी व्याख्या remote terminal driver करता है। POSIX इसे INTR character कहता है। ISIG terminal flag set होने पर driver byte को हटाता है और terminal के foreground process group के हर process को SIGINT भेजता है। इसी कारण remote foreground pipeline एक job की तरह रुक सकती है।
Local SSH client local terminal को उपयुक्त mode में रखकर keystroke channel पर भेजता है। Remote PTY canonical input, echo, special character और window size संभालता है। Full-screen editor जैसे program ये mode बदल सकते हैं, और abnormal disconnect के बाद local terminal reset होने तक display गलत दिख सकता है।
PTY के बिना Ctrl-C समझने के लिए remote terminal driver नहीं होता और terminal foreground group भी नहीं होता। RFC 4254 अलग SSH signal channel request परिभाषित करता है, लेकिन signal implement न करने वाले system को इसे ignore करने की अनुमति देता है। इसलिए client, server, wrapper और called program का cancellation behavior interactive terminal से अलग हो सकता है।
Ctrl-Z और job control यह फर्क और जल्दी दिखाते हैं। Terminal में SUSP character foreground group को SIGTSTP भेज सकता है और interactive shell बाद में job resume कर सकता है। One-shot remote command को केवल PTY मिलने से उपयोगी interactive job-control conversation नहीं मिलता। उसे suspend करने पर SSH client stopped remote group का इंतजार कर सकता है, जबकि fg चलाने के लिए shell prompt नहीं होता।
यह मानकर remote transaction को सुरक्षित न समझें कि operator सही समय पर Ctrl-C दबा देगा। Cancellation semantics remote command में डालें। Shell wrapper signal trap करके child group को terminate कर सकता है, service manager process का मालिक हो सकता है और remote timeout execution सीमित कर सकता है। फिर keyboard case के साथ disconnect case भी test करें।
ssh -tt host.example '
trap '\''printf "wrapper got INT\n" >&2; exit 130'\'' INT
printf "remote shell pid=%s\n" "$$"
sleep 300
'
Ctrl-C दबाने पर PTY path चलना चाहिए और control लौटना चाहिए। असली program के साथ दोबारा जांचें क्योंकि shell, terminal application और process supervisor अलग handler लगाते हैं। Network connection बंद करके भी test करें। PTY teardown controlling session में hangup behavior ला सकता है, जबकि output pipe रखने वाला no-PTY child SSH channel खुला रख सकता है। किसी भी mode में process को background करना detachment plan नहीं है।
लंबे काम को remote service manager या job system में submit करके job identifier लौटाएं। इससे cancellation का साफ remote target मिलता है और SSH को केवल submission की सफलता बतानी होती है। थोड़ी देर के client outage से यह तय नहीं होगा कि आधी migration आगे चलेगी या नहीं।
Exit status बचता है, wrapper उसे बदल सकता है
OpenSSH दोनों mode में remote command का exit status लौटाता है। उसका client manual कहता है कि ssh उसी status से exit करता है या error होने पर 255 देता है। RFC 4254 exit-status channel message को 32 bit unsigned value और signal termination को अलग exit-signal message के रूप में परिभाषित करता है।
PTY allocation successful status को अधिक भरोसेमंद नहीं बनाता। Shell composition तय करती है कि कौन सा status remote command status बनेगा। यह command printf का status report करती है, इसलिए failed deployment छिप सकता है:
ssh -tt host.example 'deploy; printf "finished\n"'
Result को जानबूझकर बचाएं:
ssh -T host.example '
deploy
rc=$?
printf "deploy_status=%s\n" "$rc" >&2
exit "$rc"
'
rc=$?
printf 'ssh_status=%s\n' "$rc"
exit "$rc"
Local pipeline इसे फिर छिपा सकती है। Pipeline status option के बिना shell में ssh host command | tee log आम तौर पर tee का status लौटाता है। पहले SSH output file में capture करें, tested pipeline status feature वाला shell उपयोग करें या pipeline की हर command का status पढ़ें। यह न मानें कि set -e हर pipeline, conditional या subshell ठीक कर देगा।
Status 255 अस्पष्ट है, क्योंकि OpenSSH इसे client error के लिए रखता है और remote program भी 255 से exit कर सकता है। यह फर्क जरूरी हो तो remote wrapper से protected channel पर structured completion record निकलवाएं या application status को तय range में map करें। Authentication failure, host verification failure, lost transport और literal remote 255 को एक जैसा retry नहीं करना चाहिए।
Connection setup failure remote wrapper के कुछ print करने से पहले होती है। इन्हें local रूप से classify करने के लिए client timeout और पर्याप्त SSH diagnostic रखें, लेकिन diagnostic को program data file से दूर रखें। Server wrapper शुरू कर दे तो run identifier और final status record शामिल करें ताकि caller “कभी शुरू नहीं हुआ” और “शुरू हुआ, फिर connection lost हुआ” में फर्क कर सके। इससे state बदल चुकी command को बिना सोचे retry करने से बचा जा सकता है।
Signal death में भी यही सावधानी चाहिए। Shell अक्सर signal को 128 plus signal number के रूप में दिखाता है, लेकिन SSH protocol exit signal सीधे report कर सकता है और client behavior हर मामले में local shell child status जैसा नहीं होता। Outage के बाद 128 से ऊपर हर value का अनुमान लगाने के बजाय wrapper के output status तय करें।
PTY stream मिलाता और bytes बदलता है
PTY मांगने पर remote standard output और standard error का साफ अलगाव खत्म हो जाता है। OpenSSH server implementation PTY slave को descriptor 0, 1 और 2 पर duplicate करता है। Protocol में standard error के लिए extended data channel है, लेकिन एक terminal से जुड़ा process दोनों output stream को पहले ही एक byte stream में लिख चुका होता है।
इससे आम automation pattern टूटता है:
ssh -T host.example command >result.json 2>diagnostic.log
PTY के बिना remote program का standard error diagnostic.log में और JSON result.json में जा सकता है। PTY के साथ remote warning, password prompt, banner, progress display और JSON एक साथ result.json में आ सकते हैं; local SSH diagnostic अब भी diagnostic.log में आ सकता है। Server द्वारा bytes मिलाने के बाद client redirection उन्हें अलग नहीं कर सकता।
Terminal output processing newline को carriage return plus newline में बदल सकती है। Input echo हो सकता है, canonical mode पूरी line का इंतजार कर सकता है और control character terminal function चला सकते हैं। ये सही terminal behavior हैं, लेकिन binary protocol में corruption हैं।
Terminal-aware program अक्सर color, progress bar, pager या prompt जोड़ते हैं। Terminal पर वे line buffering और pipe पर block buffering उपयोग कर सकते हैं, इसलिए no-PTY run काम करते हुए भी अटका दिखता है। संभव हो तो buffering application में ठीक करें: उसका plain output flag, unbuffered mode या logging option चुनें। Fake terminal कई variable एक साथ बदलता है और असली buffering issue छिपा सकता है।
Command machine data बनाती हो तो -T रखें और program से noninteractive format निकलवाएं। उसे सच में terminal चाहिए तो पूरे output को transcript मानें। PTY transcript को stable API की तरह parse न करें।
Agent का SSH बिना बातचीत fail होना चाहिए
Autonomous caller terminal conversation सुरक्षित रूप से नहीं संभाल सकता। Human recovery में मदद करने वाला prompt agent को wait करा सकता है, input का अनुमान लगवा सकता है या partial action को success मानने पर मजबूर कर सकता है। Credential, privilege या remote state जुड़ने से पहले SSH command को तय करना चाहिए कि interaction allowed है या नहीं।
Agent run में हर layer पर no PTY और prompt suppression रखें। SSH host authentication और host verification के लिए पहले से policy चाहिए। Privilege escalation में sudo -n उपयोग करें। Remote tool को noninteractive flag, explicit timeout और conversational prompt के बजाय file या named argument से input दें। Standard output, standard error और status अलग capture करें।
Missing password prompt को agent के सामने password या private key रखकर ठीक न करें। Authentication material और terminal behavior अलग concerns हैं। Process को PTY देने से stolen credential की शक्ति कम नहीं होती, और PTY न देने से environment में पहले से मौजूद credential सुरक्षित नहीं होता।
Sallyport credential boundary को agent process से बाहर रखता है: MCP capable agent bundled stateless sp-ssh helper के जरिए SSH action मांगता है, encrypted vault SSH key देता है और Activity journal call दर्ज करता है। Command को फिर भी साफ PTY contract चाहिए, क्योंकि secret isolation यह तय नहीं कर सकता कि remote program terminal semantics चाहता है या नहीं।
Approval भी remote prompt से अलग है। Local approval card execution से पहले परिभाषित action authorize कर सकता है; remote terminal prompt खुले session के अंदर आता है और पहले side effect के बाद भी दिख सकता है। Human authorization को remote byte stream से बाहर रखें ताकि denial का अर्थ साफ हो और log attempted action पहचान सकें।
Agent को interactive maintenance tool चाहिए तो workflow बांटें। Agent से command या request तैयार कराएं, फिर live terminal session human को दें, या tool को automation के लिए बनी noninteractive operation से बदलें। Agent को typist मानने से दोनों system का सबसे कम testable रूप मिलता है।
Mode को interface का हिस्सा चुनें
सही mode remote program के interface से तय होता है, PTY के हमेशा अच्छे या खराब होने के सामान्य rule से नहीं। Review में यह decision list उपयोग करें:
- JSON, archive और exact bytes के लिए
-Tउपयोग करें, क्योंकि यह transparent data और अलग error output बचाता है। - Unattended privileged काम में
-Tके साथsudo -nउपयोग करें, ताकि authentication wait करने के बजाय fail हो। - Human द्वारा sudo password type करने या terminal interface चलाने पर
-tउपयोग करें। - Pipe या agent launcher से
-ttकेवल missing local TTY check के override की समीक्षा के बाद उपयोग करें। - लंबे काम को remote manager में submit करें, क्योंकि PTY durable process ownership नहीं देता।
Choice को command के पास record करें। Test को केवल expected output के कुछ शब्द नहीं, बल्कि descriptor type, stream separation, cancellation और status assert करना चाहिए। Dependency upgrade के बाद terminal की जरूरत पड़े तो test fail होने दें और -t जोड़ने से पहले नया prompt या detection branch खोजें।
Selected mode को colored output या prompt से अनुमान लगाने के बजाय structured metadata के रूप में log करें। Incident कई host पर फैला हो तो यह एक field operator को कुछ rerun किए बिना terminal behavior को authentication, network और application failure से अलग करने देता है।
Server policy OpenSSH configuration या authorized key restriction से PTY मना कर सकती है। इसलिए उन्हें accidental dependency न बनाएं। Automation के लिए बनी command -T में usable रहनी चाहिए; interactive command को terminal न मिलने पर साफ fail होना चाहिए।
हर proposed -tt change को interface change मानें। Probe फिर चलाएं, दोनों local stream redirect करें, Ctrl-C भेजें, remote command से nonzero status force करें और run के बीच disconnect करें। Result को ठीक से समझा नहीं सकते तो command unattended चलाने के लिए तैयार नहीं है।
सामान्य प्रश्न
ssh -t वास्तव में क्या करता है?
यह SSH server से PTY allocate करने और remote session को उससे जोड़ने के लिए कहता है। Program को terminal descriptor दिखते हैं, remote output stream मिलती हैं और terminal input rule signal पैदा कर सकते हैं।
ssh -t और ssh -tt में क्या फर्क है?
-t local client के पास terminal होने पर PTY request force करता है। -tt local standard input terminal न होने पर भी allocation force करता है, जो pipeline और agent launcher में आम है।
क्या SSH remote command के लिए default रूप से TTY allocate करता है?
आम तौर पर दी गई remote command PTY के बिना चलती है। इसे स्पष्ट करने के लिए -T उपयोग करें और command को सच में terminal चाहिए तभी -t चुनें।
TTY न होने पर sudo SSH के जरिए fail क्यों होता है?
Password चाहिए तो sudo सामान्यतः user terminal से पढ़ता है। Automation में sudo -n और सीमित sudoers rule रखें ताकि command prompt करने के बजाय fail हो।
क्या SSH script में sudo -S सुरक्षित है?
sudo -S password transport को script की जिम्मेदारी बनाता है और secret को standard input में मिलाता है। Agent और routine automation में इससे बचें और nonprompting authorization design उपयोग करें।
क्या ssh -t .bashrc या .profile load करता है?
नहीं, PTY allocation shell startup file नहीं चुनता। जरूरत हो तो login या interactive shell साफ तौर पर मांगें, हालांकि explicit environment और executable path अधिक predictable job देते हैं।
ssh -t में stdout और stderr क्यों मिलते हैं?
OpenSSH descriptor 1 और 2 को उसी PTY slave से जोड़ता है, इसलिए server के पास भेजने को एक terminal byte stream रहता है। बाद में client redirection मूल stream दोबारा नहीं बना सकता।
क्या PTY SSH exit code बदलता है?
PTY स्वयं नहीं बदलता; OpenSSH remote command status लौटाता है। Shell wrapper, pipeline, signal termination और खास client error status 255 caller के result को बदल या छिपा सकते हैं।
Ctrl-C ssh -t के साथ और बिना अलग क्यों चलता है?
PTY terminal driver interrupt character को foreground process group के लिए SIGINT में बदलता है। PTY के बिना remote terminal foreground group नहीं होता, इसलिए cancellation SSH signal support और process structure पर निर्भर है।
क्या AI agent को prompt वाली command के लिए ssh -tt उपयोग करना चाहिए?
नहीं। Agent command को prompt रोककर उपयोगी status से fail होना चाहिए; forced terminal configuration error को अनंत conversation बना सकता है और diagnosis के output को मिला देता है।