Ekran oturumu ortam değişkenleri yeni grafik girişini yansıtacak şekilde güncelleniyor mu?


20

Linux kullanıyorum ve tüm komut satırı işlerimi tek bir ekran oturumu içinde yapmayı seviyorum, böylece terminallerimi kaybetmeden grafiksel girişimi ve benzerlerini yeniden başlatabilirim. Ancak, oturumumu kapatıp grafik oturumuma yeniden döndüğümde, bu DBus oturumları gibi tüm oturum ortamı değişkenlerimi değiştirir. Bu, tekrar oturum açtıktan sonra ekran oturumumun artık eski (ve yanlış) ortam değişkenlerine sahip olduğu anlamına gelir. Şimdi ekran oturumumdan grafik programları başlatmaya çalıştığımda, en iyi ihtimalle oturum veriyoluna bağlanamama konusunda bir uyarı veriyorlar. En kötüsü, tamamen başlayamazlar.

Yani, aradığım şey, daha sonra oluşturulan tüm ekran pencereleri yeni ortam değişkenlerini devralacak şekilde çalışan bir ekran örneğinde ortam değişkenlerini değiştirmenin bir yoludur. Bunu yapmanın bir yolu var mı?


3
Aha! Ben bunu bulmak için tüm ekran manpage üzerinden sadece disk belleği:setenv [var [string]] Set the environment variable var to value string. If only var is specified, the user will be prompted to enter a value. If no parameters are specified, the user will be prompted for both variable and value. The environment is inherited by all subsequently forked shells.
Ryan C. Thompson

Ekrana -X anahtarını kullanarak setenv'i çağırabilirsiniz. Ne yazık ki, mevcut mermi üzerinde değil, sadece sonraki tüm çatallı mermilerde çalışır.
Boris Bukh

Byobu'nun artık hem ekran hem de tmux için bir çözüm içerdiğini unutmayın .
Ryan

Yanıtlar:


8

screenEski ortamı devralınacağı için oturumdan bir kabuk komut dosyası başlatamazsınız . Ancak yeni ortam değişkenlerini eski ekran oturumuna almak için bize bir fifo verebilirsiniz. Grafik oturumunuza başladığınızda bu fifoyu doldurabilirsiniz.

#!/bin/bash
FIFO=/tmp/your_variables
[ -e $FIFO ] && cat $FIFO > /dev/null || mkfifo $FIFO

# save number of variables that follow
NVARS=2
echo $NVARS > $FIFO
echo ENV1=sth1 > $FIFO
echo ENV2=sth2 > $FIFO

Bu komut dosyasını oturum açarken arka planda başlatın (yalnızca tüm değişkenler ondan okunduğunda sona erer).

Artık fifo'dan okuyabilirsiniz, örneğin bu işlevi .bashrc

update_session() {
  FIFO=/tmp/your_variables

  NVAR=$(cat $FIFO)
  for i in $(seq $NVAR); do
    export $(cat $FIFO)
  done
  #delete the pipe, or it will not work next time 
  rm $FIFO
}

böylece eski screenoturumunuzda

update_session

pencerenin ana kabuğunu değiştirmek için bunu çalışan oturumda pencere başına bir kez yapmanız gerekmez mi?
quack quixote

Güzel, ama ~ quack'in dediği gibi, her kabuğu bağımsız olarak güncellemeniz gerekir.
dmckee

Doğru, bunu her kabukta yapmalısın screen. AFAIK screen, dışarıdan çalışan oturumlarla iletişim kurmak için hiçbir soket veya benzeri bir şey göstermez.
Benjamin Bannier

@ dmckee ama elbette her yeni screen oturumda zaten ortam değişkenleri var
Benjamin Bannier

Şimdilik bu yanıtı kabul etmeye karar verdim. Bunu gerçekten uygulamak için etrafta dolaşırsam, güncelleyeceğim. Ancak şimdilik, teorik olarak mümkün olduğunu bilmek için sıcak bulanık bir duyguya sahip olmak yeterli.
Ryan

2

Bunu yapmak için bir komut dosyası uyguladım. Buradan edinebilirsiniz: https://github.com/DarwinAwardWinner/screen-sendenv

screen-sendenv.pyİçine koyduktan sonra $PATH.bashrc dosyanızda aşağıdaki kod parçacığını kullanabilirsiniz:

VARS_TO_UPDATE="DISPLAY DBUS_SESSION_BUS_ADDRESS SESSION_MANAGER GPG_AGENT_INFO"
screen_pushenv () {
  screen-sendenv.py -t screen $VARS_TO_UPDATE
}
tmux_pushenv () {
  screen-sendenv.py -t tmux $VARS_TO_UPDATE
}
screen_pullenv () {
  tempfile=$(mktemp -q) && {
    for var in $VARS_TO_UPDATE; do
      screen sh -c "echo export $var=\$$var >> \"$tempfile\""
    done
    . "$tempfile"
    rm -f "$tempfile"
  }
}
tmux_pullenv () {
  for var in $VARS_TO_UPDATE; do
    expr="$(tmux showenv | grep "^$var=")"
    if [ -n "$expr" ]; then
      export "$expr"
    fi
  done
}

Bunu kullanmak için, ekran oturumunuza yeniden bağlanmak için çalıştırmadan screen_pushenvönce çalıştırın screen -r. Ardından, ekledikten sonra screen -rmevcut kabuklarınızdaki ortamı ile güncelleyebilirsiniz screen_pullenv. Tmux fonksiyonları, ekrana benzer başka bir terminal çoklayıcı olan tmux için de aynı şeyi yapar.


Vay be Ryan, bu çok fazla kod. Daha önce kabul edilen cevapta yanlış olan neydi (en azından ilham vericiydi)?
Benjamin Bannier

1
Eh, ben ekran (ve ayrıca tmux) ekranın geçerli penceresinde kabuk değil, ekranın kendisi için bir ortam değişkeni ayarlar bir "setenv" komutu olduğunu keşfetti. Bu, komut dosyamı kullandıktan sonra, bu ekran oturumunda yeni oluşturulan tüm pencerelerin, her birinde güncelleme komut dosyasını çalıştırmak zorunda kalmadan otomatik olarak yeni ortamı alacağı anlamına gelir. Tabii ki, bir güncelleme komut dosyası mevcut kabukları güncellemek için hala yararlı olabilir, ancak bir FIFO'dan okumak için değil, screen / tmux oturumunun kendisini yeni değerler için sorgulamak için yeniden yazmanız gerekir.
Ryan

Sen ekran / tmux oturumdan geçerli kabuk haline değişkenleri çekmeye nasıl görebilirsiniz burada yer, screen_updateve tmux_updatefonksiyonlar. Cevabımı bunların byobu'dan bağımsız bir versiyonuyla güncelleyeceğim.
Ryan

1
Her neyse, neyin yanlış olduğuna dair sorunuzu doğrudan cevaplamak için cevabınız soruyu tam olarak cevaplamıyor, daha çok ilgili bir soruyu cevaplıyor. Bir ekran oturumunun içinde çalışan bir kabuk içindeki ortam değişkenlerinin nasıl güncelleneceğini, ancak ekran oturumunun kendisinde ortam değişkenlerinin nasıl güncelleneceğini göstermezsiniz (yeni ortaya çıkan pencereler yeni değerleri devralacak şekilde). O zaman kabul ettim, çünkü hala iyi bir çözümdü, ama her zaman sonunda sorulan soruya gerçek bir cevap vermeyi amaçlamıştım . Yani, kişisel bir şey yok.
Ryan

Hey Ryan, cevap verdiğin için teşekkürler. Şimdi bahsettiğinize göre setenvbunun daha iyi olduğunu görüyorum. Bağlandığınız koddan belli değildi. Tekrar teşekkürler!
Benjamin Bannier

2

setenvEkran işlemindeki ortam değişkenlerini etkileşimli olarak değiştirmek için şu komutu kullanarak komutu çağırabilirsiniz : Ctrl- A+ :setenv( :Bir ekran komutu girmek için karakteri not edin .) Ortam değişkeni adı ve değeri istenir.

(Diğer cevaplara / yorumlara göre) bunun (üst) ekran işlemini ve dolayısıyla yeni oluşturulan ekran oturumlarını etkilediğini, ancak geçerli ekran oturumunuzu veya mevcut ekran oturumlarınızı etkilemediğini unutmayın.

İsterseniz ortam değişkeni adını ve değerini aynı anda belirleyebilirsiniz: Ctrl- A+ :setenv DISPLAY :100. Yeni ekran oturumları için DISPLAY öğesini ": 100" olarak ayarlar.

Bir ortam değişkenini kaldırmak için 'unsetenv' kullanabilirsiniz - örneğin Ctrl- A+:unsetenv DISPLAY


0

Bu muhtemelen daha basit bir çözümdür (siz karar verin). Önemli bölüm, savedisplayher screenkomut çalıştırıldığında işlevi çağıran diğer addır . Komutlar otomatik olarak çalıştırılmaz, bu nedenle ~/.bashrcçok özel bir şey yerine yerleştirilebilir ~/.ssh/rc.

savedisplay() {
    # Write latest bash display to a file, This is used to 
    # update running bash sessions for a "screen -r"
    echo "export DISPLAY=$DISPLAY" > ~/.XDISPLAY
    echo "export XAUTHORITY=$XAUTHORITY" >> ~/.XDISPLAY
    # This will only update the environment for new windows
    screen -X setenv DISPLAY $DISPLAY
    screen -X setenv XAUTHORITY $XAUTHORITY
}

# run this to update env variable in a running session
updatedisplay() {
    source ~/.XDISPLAY 
}

alias screen='savedisplay && screen'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.