Fabric: 원격 μ„œλ²„μ˜ ν™˜κ²½ λ³€μˆ˜ 및 PATH 문제(.bashrcλ₯Ό μ†Œμ‹±ν•˜μ§€ μ•ŠμŒ)

에 λ§Œλ“  2016λ…„ 10μ›” 09일  Β·  22μ½”λ©˜νŠΈ  Β·  좜처: fabric/fabric

μ•ˆλ…•ν•˜μ„Έμš”,

fab의 run λͺ…령을 μ‹€ν–‰ν•˜μ—¬ 일뢀 ν™˜κ²½ λ³€μˆ˜λ₯Ό μΆ”κ°€ν•˜κ³  경둜 λ³€μˆ˜λ₯Ό ν™•μž₯ν•  λ•Œ .bashrc νŒŒμΌμ„ λ‘œλ“œν•˜λ €κ³  ν•©λ‹ˆλ‹€(예: μ†ŒμŠ€ /home/ubuntu/.bashrc).

run('μ†ŒμŠ€/ν™ˆ/μš°λΆ„νˆ¬/.bashrc && 에코 $PATH')

이것은 λ‚˜μ—κ²Œλ§Œ λ³΄μ—¬μ€λ‹ˆλ‹€:

[[email protected]] 좜λ ₯: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin: /bin:/usr/games:/usr/local/games

원격 μ„œλ²„μ— μˆ˜λ™μœΌλ‘œ λ‘œκ·ΈμΈν•  λ•Œ ν‘œμ‹œλ˜λŠ” 훨씬 더 κΈ΄ 경둜 λͺ©λ‘ λŒ€μ‹ .

원격 ν™ˆ λ””λ ‰ν† λ¦¬μ—μ„œ .bashrc νŒŒμΌμ„ μ˜¬λ°”λ₯΄κ²Œ κ°€μ Έμ˜€κΈ° μœ„ν•΄ fab을 μ–»μœΌλ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Ό ν•©λ‹ˆκΉŒ?

κ°μ‚¬ν•©λ‹ˆλ‹€!

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

이것은 λŒ€λ°•μ΄ μ•„λ‹ˆλΌ 멋진 μΌμž…λ‹ˆλ‹€.

무엇 bashλŠ” νŒŒμΌν•˜κΈ° μ‹œμž‘ν•  λ•Œ μ†ŒμŠ€ 결정은 볡작 ν•  수 http://blog.flowblok.id.au/2013-02/shell-startup-scripts.html ν•˜κ³ μžˆλŠ” λ°λΉ„μ•ˆ / μš°λΆ„νˆ¬ (λŒ€λΆ€λΆ„μ˜ 배포판)κ°€ 일뢀 μ‚¬μš©μž μ •μ˜ /etc/profile 및 κΈ°λ³Έ ~/.bashrc .

fabμ—μ„œ μ‚¬μš©ν•˜λŠ” κΈ°λ³Έ μ‰˜μ€ /bin/bash -l -c 이고 -l λŠ” "둜그인" μ‰˜λ‘œ λ§Œλ“­λ‹ˆλ‹€. debian/ubuntu μ‚¬μš©μž 지정이 μ—†μœΌλ©΄ bash "login" μ…Έμ—μ„œ ~/.bash_profile λ₯Ό μ†Œμ‹±ν•  수 μžˆμ§€λ§Œ ~/.bashrc λŠ” μ†Œμ‹±ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μš°λΆ„νˆ¬ 16.04μ—μ„œλŠ” login-shell의 κ²½μš°μ—λ„ 기본적으둜 .bashrc λ₯Ό μ†Œμ‹±ν•˜λŠ” κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ κΈ°λ³Έ .bashrc 의 맨 μ•„λž˜μ— μΆ”κ°€λœ 행은 μ²˜λ¦¬λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λΉ„λŒ€ν™”ν˜• 싀행이 κ°μ§€λ˜λ©΄ 맨 μœ„ κ·Όμ²˜μ—μ„œ ꡬ제되기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

여기에 ubuntu-16.04 κΈ°λ³Έ μ‚¬μš©μž .bashrc 에 두 쀄을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

export VAR1=val1

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

export VAR2=val2

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
...

λ‹€μŒμ€ ν…ŒμŠ€νŠΈ 쀑인 fabfileμž…λ‹ˆλ‹€.

from fabric.api import run, env, task

<strong i="23">@task</strong>
def get_myvars():
    run("echo VAR1=$VAR1 VAR2=$VAR2")

κ²°κ³Ό:

$ fab -H testpy05.ec2.st-av.net get_myvars
[testpy05.ec2.st-av.net] Executing task 'get_myvars'
[testpy05.ec2.st-av.net] run: echo VAR1=$VAR1 VAR2=$VAR2
[testpy05.ec2.st-av.net] out: VAR1=val1 VAR2=
[testpy05.ec2.st-av.net] out: 
...

λͺ¨λ“  22 λŒ“κΈ€

이것은 λŒ€λ°•μ΄ μ•„λ‹ˆλΌ 멋진 μΌμž…λ‹ˆλ‹€.

무엇 bashλŠ” νŒŒμΌν•˜κΈ° μ‹œμž‘ν•  λ•Œ μ†ŒμŠ€ 결정은 볡작 ν•  수 http://blog.flowblok.id.au/2013-02/shell-startup-scripts.html ν•˜κ³ μžˆλŠ” λ°λΉ„μ•ˆ / μš°λΆ„νˆ¬ (λŒ€λΆ€λΆ„μ˜ 배포판)κ°€ 일뢀 μ‚¬μš©μž μ •μ˜ /etc/profile 및 κΈ°λ³Έ ~/.bashrc .

fabμ—μ„œ μ‚¬μš©ν•˜λŠ” κΈ°λ³Έ μ‰˜μ€ /bin/bash -l -c 이고 -l λŠ” "둜그인" μ‰˜λ‘œ λ§Œλ“­λ‹ˆλ‹€. debian/ubuntu μ‚¬μš©μž 지정이 μ—†μœΌλ©΄ bash "login" μ…Έμ—μ„œ ~/.bash_profile λ₯Ό μ†Œμ‹±ν•  수 μžˆμ§€λ§Œ ~/.bashrc λŠ” μ†Œμ‹±ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μš°λΆ„νˆ¬ 16.04μ—μ„œλŠ” login-shell의 κ²½μš°μ—λ„ 기본적으둜 .bashrc λ₯Ό μ†Œμ‹±ν•˜λŠ” κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ κΈ°λ³Έ .bashrc 의 맨 μ•„λž˜μ— μΆ”κ°€λœ 행은 μ²˜λ¦¬λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λΉ„λŒ€ν™”ν˜• 싀행이 κ°μ§€λ˜λ©΄ 맨 μœ„ κ·Όμ²˜μ—μ„œ ꡬ제되기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

여기에 ubuntu-16.04 κΈ°λ³Έ μ‚¬μš©μž .bashrc 에 두 쀄을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

export VAR1=val1

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

export VAR2=val2

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
...

λ‹€μŒμ€ ν…ŒμŠ€νŠΈ 쀑인 fabfileμž…λ‹ˆλ‹€.

from fabric.api import run, env, task

<strong i="23">@task</strong>
def get_myvars():
    run("echo VAR1=$VAR1 VAR2=$VAR2")

κ²°κ³Ό:

$ fab -H testpy05.ec2.st-av.net get_myvars
[testpy05.ec2.st-av.net] Executing task 'get_myvars'
[testpy05.ec2.st-av.net] run: echo VAR1=$VAR1 VAR2=$VAR2
[testpy05.ec2.st-av.net] out: VAR1=val1 VAR2=
[testpy05.ec2.st-av.net] out: 
...

ν•œ λˆˆμ— μ œλŒ€λ‘œ λ“€λ¦½λ‹ˆλ‹€. @ploxiln κ°μ‚¬ν•©λ‹ˆλ‹€!

μžμ„Έν•œ λ‹΅λ³€ κ°μ‚¬ν•©λ‹ˆλ‹€!

이것은 ν‘œμ€€ ssh λ™μž‘κ³Ό λ‹€λ₯Έ κ²ƒμœΌλ‘œ 보이며 λ””λ²„κ·Έν•˜κΈ° μ–΄λ €μ› μŠ΅λ‹ˆλ‹€. λ‚΄κ°€ μˆ˜λ™μœΌλ‘œ ssh'ν–ˆμ„ λ•Œ OSXμ—μ„œ .bash_profile을 μ‹€ν–‰ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 패브릭이 λ‹€λ₯Έ PATH 값을 κ°€μ‘Œμ„ λ•Œ λͺ¨λ‘ μ œλŒ€λ‘œ μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€.

@bitprophet 이것은 OSX 버그 일 수 μžˆμŠ΅λ‹ˆλ‹€ ??

@code-tree 패브릭 1 λ˜λŠ” 2λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆκΉŒ? 1.xλŠ” λͺ…μ‹œμ  μ…Έ 래퍼λ₯Ό μ‚¬μš©ν•˜λ―€λ‘œ ν‘œμ€€ OpenSSH ν΄λΌμ΄μ–ΈνŠΈμ™€ λ‹€λ¦…λ‹ˆλ‹€. 버전 2λŠ” λž˜ν•‘μ„ μˆ˜ν–‰ν•˜μ§€ μ•ŠμœΌλ©° sshdκ°€ μ‚¬μš©μžλ₯Ό λŒ€μ‹ ν•˜μ—¬ μ‹€ν–‰λ˜λŠ” μΈ‘λ©΄μ—μ„œ OpenSSH ν΄λΌμ΄μ–ΈνŠΈμ™€ 훨씬 더 μœ μ‚¬ν•˜κ²Œ μž‘λ™ν•΄μ•Ό ν•©λ‹ˆλ‹€.

버전 1μ—λŠ” ν•΄λ‹Ή μ‰˜ 래퍼λ₯Ό λ³€κ²½ν•˜κΈ° μœ„ν•œ λͺ‡ 가지 env ꡬ성 κ°’ μ˜΅μ…˜μ΄ μžˆμœΌλ―€λ‘œ -i 와 같은 ν”Œλž˜κ·Έλ₯Ό μΆ”κ°€ν•˜λ €κ³  ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2.2.1 버전을 μ‚¬μš©ν•˜κ³  있기 λ•Œλ¬Έμ— μ΄μƒν•©λ‹ˆλ‹€. ν˜„μž¬ λ‚΄ 앱이 μž‘λ™ν•˜λ„λ‘ ν•˜λ €λ©΄ λ‹€μŒμ„ μˆ˜ν–‰ν•΄μ•Ό ν•©λ‹ˆλ‹€.
c.run('bash -l -c "python3 ./configure.py"')
Python 3을 μ„€μΉ˜ν•  λ•Œ Fabricμ—μ„œ μ‹€ν–‰λ˜μ§€ μ•ŠλŠ” .bash_profile λ₯Ό 톡해 PATH에 μΆ”κ°€λ˜μ—ˆμŠ΅λ‹ˆλ‹€. ν‘œμ€€ λ‚΄μž₯ sshd ꡬ성도 μˆ˜μ •ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

μ΄μƒν•©λ‹ˆλ‹€. λ³΅μ œν•  수 μžˆλŠ”μ§€ 확인해야 ν•©λ‹ˆλ‹€. λ‚΄κ°€ μ˜λ―Έν•˜λŠ” λ°”λ₯Ό 증λͺ…ν•˜κΈ° μœ„ν•΄ λΉ λ₯Έ μ˜¨μ „ν•œ 좔적을 μˆ˜ν–‰ν–ˆμŠ΅λ‹ˆλ‹€. Fabric 2λŠ” 'νŠΉλ³„ν•œ' μž‘μ—…μ„ μˆ˜ν–‰ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. re: sshd 기반 μ‹€ν–‰:

@code-tree λ˜ν•œ κ°€λŠ₯ν•˜λ©΄ μ‹€ν–‰ 쀑인 ν•­λͺ©κ³Ό 기타 ν™˜κ²½ μ„ΈλΆ€ 정보(ν΄λΌμ΄μ–ΈνŠΈ 및 μ„œλ²„ OS/버전 λ“±)에 λŒ€ν•œ μžμ„Έν•œ 정보λ₯Ό κ²Œμ‹œν•˜μ‹­μ‹œμ˜€.

λ¬Όλ‘ , 이전 OSX 버전을 μ„œλ²„λ‘œ μ‹€ν–‰ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μ΅œμ‹  MacOSμ—μ„œ λͺ¨λ“  것이 μ œλŒ€λ‘œ μž‘λ™ν•˜λŠ”μ§€ 확인할 수 μžˆλ‹€λ©΄ 였 잘 λ©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 그렇지 μ•Šμ€ 경우 일반적으둜 MacOSλ₯Ό μ„œλ²„λ‘œ μ‚¬μš©ν•˜λŠ” 데 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆκΉŒ?

  • ν΄λΌμ΄μ–ΈνŠΈ: Ubuntu 16.04, Python 3.6.6, OpenSSH 7.2p2, Bash 4.3.48, Fabric 2.2.1
  • μ„œλ²„: OSX 10.11, Python 3.6.6, OpenSSH 6.9p1, Bash 3.2.57

참고둜 이것이 μ‹€μ œλ‘œ μ˜€μ§„μ˜ κ²½μš°μΈμ§€ κΆκΈˆν•©λ‹ˆλ‹€.

OSXμ—μ„œ .bash_profile을 μ‹€ν–‰ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— νŒ¨λΈŒλ¦­μ— λ‹€λ₯Έ PATH 값이 μžˆμŠ΅λ‹ˆλ‹€.

λŒ€μ‹  Fabric 2κ°€ 둜컬 ν™˜κ²½ λ³€μˆ˜λ₯Ό νŒŒμ΄ν”„λ‘œ λΆ„λ₯˜ν•œλ‹€λŠ” μΈ‘λ©΄μ—μ„œ ssh 와 λ‹€λ₯Έ #1744의 μ˜ˆκ°€ 될 수 μžˆμŠ΅λ‹ˆκΉŒ? (문제의 μ •ν™•ν•œ env λ³€μˆ˜μ™€ 둜컬 및 원격 μœ μ‚¬ 여뢀에 따라 λ‹€λ¦…λ‹ˆλ‹€. @code-treeλŠ” 둜컬 및 원격 bash_profile의 μ •ν™•ν•œ 값을 λ‹€μ‹œ ν™•μΈν•˜μ—¬ 이 이둠을 μ‰½κ²Œ λ°˜μ¦ν•  수 μžˆμŠ΅λ‹ˆλ‹€... 😁)


κ·ΈλŸ¬λ‚˜ λ‚˜λŠ” 이 문제λ₯Ό μ§μ ‘μ μœΌλ‘œ ν•΄κ²°ν•  κ²ƒμž…λ‹ˆλ‹€. λ‚΄κ°€ 미친 것이 μ•„λ‹ˆλΌλŠ” 것을 μ•ŒκΈ° μœ„ν•΄μ„œμž…λ‹ˆλ‹€. sshdκ°€ μ‰˜κ³Ό μ†ŒμŠ€ 파일의 κ΄€μ μ—μ„œ 무엇을 ν•˜κ³  μžˆλŠ”μ§€μ— λŒ€ν•œ μ΄ν•΄μž…λ‹ˆλ‹€.

λ˜ν•œ 이것이 μ‰˜ 및 μ‹œμž‘ νŒŒμΌμ— κ΄€ν•œ #1816의 μ‹œλ‚˜λ¦¬μ˜€/지λŠ₯κ³Ό 관련이 μžˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€. ssh ν•œ λ°©ν–₯으둜 λ™μž‘ν•˜κ³  Fabric이 λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ λ™μž‘ν•œλ‹€λŠ” μ£Όμž₯ λ•Œλ¬Έμ— _μ•„λ§ˆλ„_ μ§μ ‘μ μœΌλ‘œ 관련이 μ—†μ§€λ§Œ("sshdκ°€ μ‰˜μ„ μ •μƒμ μœΌλ‘œ ν˜ΈμΆœν•˜λŠ” 방법"κ³Ό 닀름) μ–΄μ¨Œλ“  μ—°κ²°ν•  κ°€μΉ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€.

μ§€λ‚œ λͺ‡ κ°œμ›” λ™μ•ˆ ν–ˆλ˜ κ²ƒμœΌλ‘œ κΈ°μ–΅ν•˜λŠ” κΉŠμ€ sshd μ½”λ“œ 닀이빙을 μš°μ—°νžˆ λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€. μ§œμ¦λ‚˜λŠ” μΌμ΄μ§€λ§Œ μ§€κΈˆμ€ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€. νŽΈμ§‘: μ•„ 인증 전에 λͺ…령을 μ‹€ν–‰ν•˜λŠ” 것과 관련이 μ—†λŠ” Paramiko 문제(ν˜Όλž€μŠ€λŸ¬μš΄ 점이 μ—†κΈ° λ•Œλ¬Έμ— μ—°κ²°λ˜μ§€ μ•ŠμŒ)라고 μƒκ°ν•©λ‹ˆλ‹€. μ’‹μ•„μš”.

μ’‹μŠ΅λ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄ μš°λ¦¬κ°€ exec λͺ…령을 μš”μ²­ν•  λ•Œ μ‹€μ œλ‘œ 무슨 일이 μΌμ–΄λ‚˜κ³  μžˆμŠ΅λ‹ˆκΉŒ?

  • SSH-the-protocol은 shell 채널 μš”μ²­(μ‚¬μš©μžκ°€ μ •μ˜ν•œ 둜그인 μ…Έ ν”„λ‘œκ·Έλž¨μ„ λ‘œλ“œν•˜κ³  command ν•˜μ§€ μ•ŠμŒ) λ˜λŠ” exec 채널을 μš”μ²­ν•©λ‹ˆλ‹€. μš”μ²­("경둜λ₯Ό 포함할 수 μžˆλŠ” 주어진 λͺ…λ Ή λ¬Έμžμ—΄μ„ 싀행함"이라고 λ§ν•˜κ³  더 이상 μ§€μ •ν•˜μ§€ μ•ŠμŒ)
  • ParamikoλŠ” μœ„μ—μ„œ 찾은 κ²ƒμ²˜λŸΌ ν›„μžλ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  • κ·Έλ ‡λ‹€λ©΄ OpenSSH μžμ²΄λŠ” μ‹€μ œλ‘œ 무엇을 ν•˜κ³  μžˆμŠ΅λ‹ˆκΉŒ? openssh-portable( 775f8a23f2353f5869003c57a213d14b28e0736e )의 둜컬 체크아웃을 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

κΈ€μŽ„, λ¨Όμ € λ‚΄κ°€ μ’€ λΉ™λΉ™ 돌게. λ‚΄κ°€ν•˜κ³ μ‹œ DEBUG3 μˆ˜μ€€μ˜ λ‘œκ·Έμ—μ„œ λ³Ό (! OpenSSHλ₯Ό 6.7λ₯Ό μ‹€ν–‰ν•˜λŠ”) μž„μ˜μ˜ λ°λΉ„μ•ˆ 8.10 μ»¨ν…Œμ΄λ„ˆμ— λŒ€ν•΄ μ‹€ν–‰ ssh localhost whoami :

debug1: server_input_channel_req: channel 0 request exec reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req exec
Starting session: command for root from 172.17.0.1 port 42598

fab -H localhost -- whoami :

debug1: server_input_channel_req: channel 0 request exec reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req exec
Starting session: command for root from 172.17.0.1 port 42610

μ•Œκ² μŠ΅λ‹ˆλ‹€. λ‘˜ λ‹€ exec ...그건 λ‹Ήμ—°ν•©λ‹ˆλ‹€. ν”„λ‘œμ„ΈμŠ€ νŠΈλ¦¬μ—μ„œ λ‹€λ₯Έ 것이 μžˆμŠ΅λ‹ˆκΉŒ? μ—†μ–΄μ•Ό ν•˜κ³ ...μ—†μ–΄μ•Ό ν•©λ‹ˆλ‹€. λ‘˜ λ‹€ λ‹€μŒκ³Ό 같이 λ³΄μž…λ‹ˆλ‹€.

sshd,1 -D -e
  └─sshd,1535
      └─pstree,1537 -alpU

κ·Έλž˜μ„œ, ν™•μ‹€νžˆ ν”Œλ ˆμ΄ 쀑인 μ‰˜μ΄ μ—†μŠ΅λ‹ˆκΉŒ? λ­ν•˜λŠ”κ±°μ•Ό? && 와 같은 μ‘°μž‘ν•œ 것을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?

μ € ν•  수 μžˆμ–΄μš”! 예: whoami && id λŠ” 잘 μž‘λ™ν•©λ‹ˆλ‹€. μœ λ‹‰μŠ€ ν”„λ‘œμ„ΈμŠ€ μ œμ–΄μ— λŒ€ν•œ λ‚˜μ˜ 이해λ₯Ό κ°μ•ˆν•  λ•Œ 이것은 μ•½κ°„ μ΄μƒν•©λ‹ˆλ‹€. sshdκ°€ 말 κ·ΈλŒ€λ‘œ exec(string) ν•˜λŠ” 것 κ°™μ§€λŠ” μ•Šμ§€λ§Œ μ‰˜μ„ μ‚¬μš©ν•˜μ—¬ ν•΄μ„ν•˜λŠ” 경우 pstree μ—†μŠ΅λ‹ˆκΉŒ?

이제 openssh-portable을 μžμ„Ένžˆ μ‚΄νŽ΄λ³΄κ³  무엇이 무엇인지 μ‚΄νŽ΄λ΄μ•Ό ν•  λ•ŒλΌκ³  μƒκ°ν•©λ‹ˆλ‹€.


λ˜ν•œ 2016λ…„ 12μ›” https://github.com/paramiko/paramiko/pull/398#issuecomment -264281759μ—μ„œμ™€ 같이 과거에 이 μΆ”μ μ˜ 일뢀λ₯Ό _did_ ν–ˆμŠ΅λ‹ˆλ‹€(κ·ΈλŸ¬λ‚˜ λ‹€λ₯Έ 이유/초점으둜). μ™„μ „νžˆ 잊고 μžˆμ—ˆλ‹€...


pstree μ—μ„œ μ‰˜μ΄ 보이지 μ•ŠλŠ” μ΄μœ λŠ” execve μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 도 replace-me μŠ€νƒ€μΌμ˜ exec ν˜ΈμΆœμ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ•„λž˜ 주석을 μ°Έμ‘°ν•˜μ„Έμš”.)


μ–΄μ¨Œλ“ , κ·Έλž˜μ„œ! 이것은 μ—¬μ „νžˆ ​​Fabric 및 OpenSSH의 ν΄λΌμ΄μ–ΈνŠΈκ°€ μ…Έ μ‹€ν–‰ μΈ‘λ©΄μ—μ„œ μ •ν™•νžˆ λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κ³  μžˆμŒμ„ μ˜λ―Έν•΄μ•Ό ν•©λ‹ˆλ‹€. κ·Έλ“€ 쀑 λˆ„κ΅¬λ„ ν•˜μ§€ μ•ŠλŠ” 것은 OpenSSH μ½”λ“œλ² μ΄μŠ€μ˜ μ΄λŸ¬ν•œ 뢀뢄을 μˆ˜μ •ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. @code-tree의 macOS μˆ˜μ€€ μ‚¬μš©μž 및 κ΅¬μ„±λœ 셸에 따라 bash 의 μ‹€μ œ κ°’κ³Ό ν•¨κ»˜ 항상 bash -c "python3 ./configure.py" 와 κ°™μ•„μ•Ό ν•©λ‹ˆλ‹€.

env var transmission이 차별화 μš”μ†ŒλΌλŠ” λ‚΄ 직감이 μ •ν™•ν•œμ§€ κΆκΈˆν•©λ‹ˆλ‹€. 두 μ‹€ν–‰ ν™˜κ²½μ΄ μ–΄λ–»κ²Œ λ‹€λ₯Ό 수 μžˆλŠ”μ§€ 생각할 수 μžˆλŠ” μœ μΌν•œ μ΄μœ μž…λ‹ˆλ‹€. λ‚΄ CLI 쀑심 ν…ŒμŠ€νŠΈμ˜ FWIWμ—μ„œ env λŠ” 두 μ‹œμŠ€ν…œ λͺ¨λ‘μ—μ„œ λ™μΌν•˜κ²Œ λ³΄κ³ ν•˜λ©° λ‹€λ₯Έ ν™˜κ²½ κ΄€λ ¨ λ¬Έμ œμ— 관계없이 _default_ λ™μž‘(SSH λ³΄μ•ˆ μ •μ±…μœΌλ‘œ 인해)은 항상 둜컬 ν™˜κ²½μ΄ "λˆ„μˆ˜"λ˜μ§€ μ•Šμ•„μ•Ό ν•©λ‹ˆλ‹€. λ°˜λŒ€νŽΈ.

예, sshdκ°€ 항상 μ‚¬μš©μžμ˜ μ…Έμ—μ„œ λͺ…λ Ή λ¬Έμžμ—΄μ„ μ‹€ν–‰ν•œλ‹€κ³  ν™•μ‹ ν•©λ‹ˆλ‹€(/etc/passwd에 ꡬ성됨). κ·ΈλŸ¬λ‚˜ λͺ…λ Ή λ¬Έμžμ—΄μ„ ꡬ문 λΆ„μ„ν•˜κ³  단일 λͺ…λ Ήμž„μ„ κ²°μ •ν•  수 μžˆλŠ” 경우 λͺ…λ Ή λ¬Έμžμ—΄ μ•žμ— "exec"κ°€ μΆ”κ°€λ©λ‹ˆλ‹€.

$ ssh testdeploy02.ec2.st-av.net pstree -a
...
  |-sshd -D
  |   `-sshd 
  |       `-sshd  
  |           `-pstree -a
$ ssh testdeploy02.ec2.st-av.net 'pstree -a && sleep 1'
...
  |-sshd -D
  |   `-sshd 
  |       `-sshd  
  |           `-bash -c pstree -a && sleep 1
  |               `-pstree -a
$ ssh testdeploy02.ec2.st-av.net 'VAR=-a sh -c "exec pstree \$VAR"'
...
  |-sshd -D
  |   `-sshd 
  |       `-sshd  
  |           `-pstree -a

ν™˜κ²½ λ³€μˆ˜μ˜ 경우 λŒ€λΆ€λΆ„ ssh ν΄λΌμ΄μ–ΈνŠΈ 및 sshd μ„œλ²„ ꡬ성에 μ˜ν•΄ μ œμ–΄λ©λ‹ˆλ‹€.

$ grep Env /etc/ssh/*_config
/etc/ssh/ssh_config:    SendEnv LANG LC_*
/etc/ssh/sshd_config:AcceptEnv LANG LC_*

λ”°λΌμ„œ ssh ν΄λΌμ΄μ–ΈνŠΈλŠ” 일뢀 λ³€μˆ˜(λͺ…λ Ή λ¬Έμžμ—΄ 자체 μ™ΈλΆ€)λ₯Ό λͺ…μ‹œμ μœΌλ‘œ 보내고 sshd에 μ˜ν•΄ ν•„ν„°λ§λ©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λΆ„λͺ…νžˆ λͺ‡ 가지 μ˜ˆμ™Έκ°€ μžˆμŠ΅λ‹ˆλ‹€.

$ ssh testdeploy02.ec2.st-av.net env | grep TERM
$ ssh -t testdeploy02.ec2.st-av.net env | grep TERM
TERM=xterm-256color

μ‹€μ œλ‘œ "μ‰˜μ„ 단일 λͺ…λ ΉμœΌλ‘œ κ΅μ²΄ν•˜λŠ” μžλ™ μ‹€ν–‰"λ™μž‘μ΄ bash의 κΈ°λŠ₯이라고 μƒκ°ν•©λ‹ˆλ‹€.

$ dash -c "pstree -a"
...
  β”œβ”€sshd -D
  β”‚   └─sshd 
  β”‚       └─sshd  
  β”‚           └─bash
  β”‚               └─dash -c pstree -a
  β”‚                   └─pstree -a
$ bash -c "pstree -a"
  β”œβ”€sshd -D
  β”‚   └─sshd 
  β”‚       └─sshd  
  β”‚           └─bash
  β”‚               └─pstree -a

νŽΈμ§‘: 완전성을 μœ„ν•΄:

$ bash -c "pstree -a && sleep 1"
  β”œβ”€sshd -D
  β”‚   └─sshd 
  β”‚       └─sshd  
  β”‚           └─bash
  β”‚               └─bash -c pstree -a && sleep 1
  β”‚                   └─pstree -a

μ•„ 예, μ œκ°€ 잘λͺ» μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. execve λŠ” sshd μžμ‹ proc 이 λŒ€μ²΄λœλ‹€λŠ” 것을 μ˜λ―Έν•˜λ―€λ‘œ κ·Έ 이후에 μΌμ–΄λ‚˜λŠ” 일은 μ…Έ μžμ²΄μ™€ -c xxx 달렀 μžˆμŠ΅λ‹ˆλ‹€. λ‚΄ ν…ŒμŠ€νŠΈλŠ” zsh, fwiw에 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ @ploxiln 예 , env varsκ°€ μžˆλŠ” 것은 μœ„μ— 링크된 λ‹€λ₯Έ 티켓을 μ°Έμ‘°ν•˜κ³  μžˆμ§€λ§Œ @code-treeκ°€ μ‹€μ œλ‘œ λ‹€λ₯Έ 티켓을 κ²½ν—˜ν•˜κ³ 

μ£„μ†‘ν•©λ‹ˆλ‹€. 잘λͺ»λœ 경보인 것 κ°™μŠ΅λ‹ˆλ‹€. ssh 인라인을 톡해 λͺ…령을 μ‹€ν–‰ν•˜λŠ” 것과 sshλ₯Ό 톡해 λ‘œκ·ΈμΈν•œ ν›„ μ‹€ν–‰ν•˜λŠ” 것 사이에 차이가 μžˆλ‹€λŠ” 것을 μ•Œμ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€. ssh host 'echo $PATH' ν•˜λ©΄ 둜그인 ν›„ echo $PATH κ°€ μ œλŒ€λ‘œ μž‘λ™ν•˜λŠ” PATH도 μ—…λ°μ΄νŠΈλ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” μ—¬μ „νžˆ sshκ°€ μ™œ μ΄κ²ƒμ„ν•˜λŠ”μ§€ μ •λ§λ‘œ μ΄ν•΄ν•˜μ§€ λͺ»ν•©λ‹ˆλ‹€ (μ‹€μ œλ‘œ ssh host 'bash -l -c "python3 ./configure.py"' ν•΄μ•Ό ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€). κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  이것은 κ²°κ΅­ Fabric λ¬Έμ œκ°€ μ•„λ‹ˆλΌκ³  λ§ν•˜λŠ” 것이 μ•ˆμ „ν•©λ‹ˆλ‹€. ν˜Όλž€μ„ λ“œλ € μ£„μ†‘ν•©λ‹ˆλ‹€.

@code-tree μ•žμ„œ μ–ΈκΈ‰ν•œ 것과 관련이 μžˆμŠ΅λ‹ˆλ‹€. μ…Έμ—λŠ” μž‘λ™ν•˜λŠ” λͺ‡ 가지 λ‹€λ₯Έ λͺ¨λ“œκ°€ 있으며, ν”νžˆ '둜그인' 및 'λŒ€ν™”ν˜•'이라고 ν•©λ‹ˆλ‹€(일반적으둜 λ‘˜ λ‹€ κ³ λ €λ˜μ§€ μ•ŠλŠ” κΈ°λ³Έ λͺ¨λ“œ μœ„μ— 있음). μ‰˜μ΄ μ‹€ν–‰ 쀑이면 λ‘œλ“œν•˜λŠ” rc 파일 μ„ΈνŠΈκ°€ λ³€κ²½λ©λ‹ˆλ‹€.

μ—¬κΈ°μ„œ λ‘λ“œλŸ¬μ§„ 점은 bash -c xxx κ°€ "λŒ€ν™”ν˜•"으둜 κ°„μ£Όλ˜μ§€ μ•ŠμœΌλ―€λ‘œ .bash_profile 와 같은 νŠΉμ • 파일 λ‘œλ“œλ₯Ό κ±΄λ„ˆλ›°μ§€λ§Œ bash 없이 -c bash λ₯Ό μ‹€ν–‰ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 일반적으둜 λŒ€ν™”ν˜•μ΄λ©° ν”„λ‘œν•„ νŒŒμΌμ„ λ‘œλ“œν•©λ‹ˆλ‹€.

μœ„μ—μ„œ λ³΄μ•˜λ“―μ΄ sshdλŠ” 단일 λͺ…령을 μ‹€ν–‰ν•˜λ„λ‘ μš”μ²­ν•  λ•Œ 항상 bash -c <command send down the pipe> λ₯Ό μ‹€ν–‰ν•˜λ―€λ‘œ(Fabricκ³Ό 같이 λ˜λŠ” ssh host command κ°€ μˆ˜ν–‰ν•˜λŠ” κ²ƒμ²˜λŸΌ) 항상 λΉ„λŒ€ν™”μ‹ λͺ¨λ“œμ— μžˆμŠ΅λ‹ˆλ‹€. (Fabric 1이 ν•˜λŠ” 일을 ν•˜κ³  -l μžμ‹ μ˜ μ€‘μ²©λœ μ‰˜μ„ μ‹€ν–‰ν•˜μ§€ μ•ŠλŠ” ν•œ ...ν•˜μ§€λ§Œ bash -c "bash -l -c \"oh god escaping is hard help\"" ν•˜κ³  있고 μ§€κΈˆ κ°€μ„œ 일뢀 πŸ₯ƒλ₯Ό 가지렀고 ν•©λ‹ˆλ‹€.

μ–΄μ¨Œλ“  λ‹€ μžƒλŠ” 건 μ•„λ‹ˆλ‹ˆκΉŒ λͺ‡ 년에 ν•œ λ²ˆμ”© 이 뢀뢄에 λŒ€ν•œ 기얡을 μƒˆλ‘œκ³ μΉ¨ν•΄μ•Ό ν•˜λŠ” 것 κ°™μœΌλ‹ˆκΉŒ μ–΄...이제 기뢄이 μƒμΎŒν•΄ πŸ˜†

이것은 λŒ€λ°•μ΄ μ•„λ‹ˆλΌ 멋진 μΌμž…λ‹ˆλ‹€.

무엇 bashλŠ” νŒŒμΌν•˜κΈ° μ‹œμž‘ν•  λ•Œ μ†ŒμŠ€ 결정은 볡작 ν•  수 http://blog.flowblok.id.au/2013-02/shell-startup-scripts.html ν•˜κ³ μžˆλŠ” λ°λΉ„μ•ˆ / μš°λΆ„νˆ¬ (λŒ€λΆ€λΆ„μ˜ 배포판)κ°€ 일뢀 μ‚¬μš©μž μ •μ˜ /etc/profile 및 κΈ°λ³Έ ~/.bashrc .

fabμ—μ„œ μ‚¬μš©ν•˜λŠ” κΈ°λ³Έ μ‰˜μ€ /bin/bash -l -c 이고 -l λŠ” "둜그인" μ‰˜λ‘œ λ§Œλ“­λ‹ˆλ‹€. debian/ubuntu μ‚¬μš©μž 지정이 μ—†μœΌλ©΄ bash "login" μ…Έμ—μ„œ ~/.bash_profile λ₯Ό μ†Œμ‹±ν•  수 μžˆμ§€λ§Œ ~/.bashrc λŠ” μ†Œμ‹±ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μš°λΆ„νˆ¬ 16.04μ—μ„œλŠ” login-shell의 κ²½μš°μ—λ„ 기본적으둜 .bashrc λ₯Ό μ†Œμ‹±ν•˜λŠ” κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ κΈ°λ³Έ .bashrc 의 맨 μ•„λž˜μ— μΆ”κ°€λœ 행은 μ²˜λ¦¬λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λΉ„λŒ€ν™”ν˜• 싀행이 κ°μ§€λ˜λ©΄ 맨 μœ„ κ·Όμ²˜μ—μ„œ ꡬ제되기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

여기에 ubuntu-16.04 κΈ°λ³Έ μ‚¬μš©μž .bashrc 에 두 쀄을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

export VAR1=val1

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

export VAR2=val2

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
...

λ‹€μŒμ€ ν…ŒμŠ€νŠΈ 쀑인 fabfileμž…λ‹ˆλ‹€.

from fabric.api import run, env, task

<strong i="24">@task</strong>
def get_myvars():
    run("echo VAR1=$VAR1 VAR2=$VAR2")

κ²°κ³Ό:

$ fab -H testpy05.ec2.st-av.net get_myvars
[testpy05.ec2.st-av.net] Executing task 'get_myvars'
[testpy05.ec2.st-av.net] run: echo VAR1=$VAR1 VAR2=$VAR2
[testpy05.ec2.st-av.net] out: VAR1=val1 VAR2=
[testpy05.ec2.st-av.net] out: 
...

당신은 λ‚΄ 생λͺ…을 κ΅¬ν–ˆμŠ΅λ‹ˆλ‹€. 이것은 λ‚΄κ°€ μ°ΎλŠ” μ™„λ²½ν•œ λ‹΅λ³€μž…λ‹ˆλ‹€ :) λ§Žμ€ κ°μ‚¬ν•©λ‹ˆλ‹€!

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰