2016-04-03 31 views
1

Çalışma alanımdaki bilgileri başka bir komuta aktarmaya çalışıyorum ve her çalışma alanı aynı bilgileri içerdiği için, bunu tanımlamak için yalnızca farklı bir sayı ile, tek bir değişkenin bazı değişken adlarında tek bir karakter olduğu 10 işlev yazdım. Bunun çok basitleştirilebileceğini hissediyorum, ancak durumumda herhangi bir döngü çalışmasının nasıl olduğunu anlayamıyorum. İşte 10 benzer işlevi for döngüsüne çevirmek mümkün mü?

#!/bin/bash 

# Include config file. 
. $(dirname $0)/config 

getWorkspaceInfo(){ 
    filledWorkspaces=$(i3-msg -t get_workspaces | grep -Po '"'"name"'"\s*:\s*"\K([^"]*)') 
    currentWorkspace=$(i3-msg -t get_outputs | sed 's/.*"current_workspace":"\([^"]*\)".*/\1/') 
} 

# Determine the status of each workspace. Current is green, unfocused is white, empty is grey. 
workspace1(){ 
    if [[ ${currentWorkspace} -eq 1 ]]; then 
     workspace1Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "1") == "" ]]; then 
     workspace1Color=${grey} 
    else 
     workspace1Color=${foreground} 
    fi 

    echo "%{F${workspace1Color}}${workspace1Name}" 
} 

workspace2(){ 
    if [[ ${currentWorkspace} -eq 2 ]]; then 
     workspace2Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "2") == "" ]]; then 
     workspace2Color=${grey} 
    else 
     workspace2Color=${foreground} 
    fi 

    echo "%{F${workspace2Color}}${workspace2Name}" 
} 

workspace3(){ 
    if [[ ${currentWorkspace} -eq 3 ]]; then 
     workspace3Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "3") == "" ]]; then 
     workspace3Color=${grey} 
    else 
     workspace3Color=${foreground} 
    fi 

    echo "%{F${workspace3Color}}${workspace3Name}" 
} 

workspace4(){ 
    if [[ ${currentWorkspace} -eq 4 ]]; then 
     workspace4Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "4") == "" ]]; then 
     workspace4Color=${grey} 
    else 
     workspace4Color=${foreground} 
    fi 

    echo "%{F${workspace4Color}}${workspace4Name}" 
} 

workspace5(){ 
    if [[ ${currentWorkspace} -eq 5 ]]; then 
     workspace5Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "5") == "" ]]; then 
     workspace5Color=${grey} 
    else 
     workspace5Color=${foreground} 
    fi 

    echo "%{F${workspace5Color}}${workspace5Name}" 
} 

workspace6(){ 
    if [[ ${currentWorkspace} -eq 6 ]]; then 
     workspace6Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "6") == "" ]]; then 
     workspace6Color=${grey} 
    else 
     workspace6Color=${foreground} 
    fi 

    echo "%{F${workspace6Color}}${workspace6Name}" 
} 

workspace7(){ 
    if [[ ${currentWorkspace} -eq 7 ]]; then 
     workspace7Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "7") == "" ]]; then 
     workspace7Color=${grey} 
    else 
     workspace7Color=${foreground} 
    fi 

    echo "%{F${workspace7Color}}${workspace7Name}" 
} 

workspace8(){ 
    if [[ ${currentWorkspace} -eq 8 ]]; then 
     workspace8Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "8") == "" ]]; then 
     workspace8Color=${grey} 
    else 
     workspace8Color=${foreground} 
    fi 

    echo "%{F${workspace8Color}}${workspace8Name}" 
} 

workspace9(){ 
    if [[ ${currentWorkspace} -eq 9 ]]; then 
     workspace9Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "9") == "" ]]; then 
     workspace9Color=${grey} 
    else 
     workspace9Color=${foreground} 
    fi 

    echo "%{F${workspace9Color}}${workspace9Name}" 
} 

workspace10(){ 
    if [[ ${currentWorkspace} -eq 10 ]]; then 
     workspace10Color=${green} 
    elif [[ $(echo ${filledWorkspaces} | grep -w "10") == "" ]]; then 
     workspace10Color=${grey} 
    else 
     workspace10Color=${foreground} 
    fi 

    echo "%{F${workspace10Color}}${workspace10Name}" 
} 

# Pipe functions to the bar infinitely. 
while true; do 
    getWorkspaceInfo 
    echo "%{c}$(workspace1)${separator}$(workspace2)${separator}$(workspace3)${separator}$(workspace4)${separator}$(workspace5)${separator}$(workspace6)${separator}$(workspace7)${separator}$(workspace8)${separator}$(workspace9)${separator}$(workspace10)" 
done | lemonbar -g ${panelWidth}x${panelHeight}+${panelX}+${bottomPanelY} -f "${font}" -f "${iconFont}" -B "${background}" -F "${foreground}" -p -d | \ 
    while true; do read line; eval $line; done & 

Ben ithal ediyorum yapılandırma dosyasıdır:

Hepsi burada 10 fonksiyonları içeren benim senaryom

#!/bin/bash 

# Outside sources 
xres="$HOME/.Xresources" 
i3config="$HOME/.config/i3/config" 

# Fetch information from Xresources 
background=$(cat ${xres} | grep -i background | tail -c 8) 
foreground=$(cat ${xres} | grep -i foreground | tail -c 8) 
black=$(cat ${xres} | grep -i color0 | tail -c 8) 
grey=$(cat ${xres} | grep -i color8 | tail -c 8) 
red=$(cat ${xres} | grep -i color9 | tail -c 8) 
green=$(cat ${xres} | grep -i color10 | tail -c 8) 
yellow=$(cat ${xres} | grep -i color11 | tail -c 8) 
blue=$(cat ${xres} | grep -i color12 | tail -c 8) 
magenta=$(cat ${xres} | grep -i color13 | tail -c 8) 
cyan=$(cat ${xres} | grep -i color14 | tail -c 8) 
white=$(cat ${xres} | grep -i color15 | tail -c 8) 

# Fetch information from i3 config 
gapSize=$(cat ${i3config} | grep -i "gaps inner" | awk '{print $3}') 

# Workspace names -- independant from i3 config -- workspaces in i3 config should be named numbers 1-10. 
workspace1Name="Web Browser" 
workspace2Name="Terminal" 
workspace3Name="Text Editor" 
workspace4Name="Unspecified" 
workspace5Name="Unspecified" 
workspace6Name="Unspecified" 
workspace7Name="Unspecified" 
workspace8Name="Unspecified" 
workspace9Name="Messenger" 
workspace10Name="Music Player" 

# Fonts 
font="InputSans-10" 
iconFont="FontAwesome" 

separator="%{F$foreground} |│| " 

# Panel size 
screenWidth=$(xrandr | grep 'Screen 0'| awk '{print $8}') 
screenHeight=$(xrandr | grep 'Screen 0' | awk '{print $10}' | tr -d ",") 

panelHeight=$((${gapSize} * 2)) 
panelWidth=$((${screenWidth} - ${panelHeight})) 
panelX=${gapSize} 
topPanelY=${gapSize} 
bottomPanelY=$((${screenHeight} - ${panelHeight} - ${gapSize})) 
+0

İşlevin aslında "workspace1color" genel değişkenini ayarlamanız gerekiyor mu? Daha sonraki bazı kodlarda, işlev çağrıldıktan sonra, fonksiyonun ayarladığı "workspace1color" işlevini kullanması gerekir mi? – ruakh

+0

Hayır, betiğin son satırı - tüm işlevlerin bildirilmesinden sonra gelir - hepsini çağırır ve sonra çıkışı verir. – Wulfre

+0

Bir kedinin yavaş işleyişini, "cat" 'ın yararsız kullanımlarından kaçınarak kaydedebilirsiniz: 'red = $ (grep -i color9 $ xres | tail -c 8)'. Daha sonra, 'grep | awk' bir * anti-pattern'tir * çünkü awk grep'te yerleşiktir:' xrandr | awk '/ Ekran 0/{print $ 8}' '. – Jens

cevap

4

Peki, en basit düzeltme gibi bir şey yazmaktır:

function all_10_workspaces() { 
    local i 
    for i in {1..10} ; do 
     local workspaceNameVar="workspace${i}Name" 
     local workspaceName="${!workspaceNameVar}" 

     local color 
     if ((currentWorkspace == 1)) ; then 
      color=$green 
     elif grep -w -q "$i" <<< "$filledWorkspaces" ; then 
      color=$foreground 
     else 
      color=$grey 
     fi 

     echo "%{F$color}$workspaceName" 
    done 
} 

. . . ancak bunun yerine dizileri kullanmayı düşünmelisiniz. Örneğin:

workspaceNames=(
    ''    # 0 (no such workspace) 
    'Web Browser' # 1 
    Terminal  # 2 
    'Text Editor' # 3 
    Unspecified # 4 
    Unspecified # 5 
    Unspecified # 6 
    Unspecified # 7 
    Unspecified # 8 
    Messenger  # 9 
    'Music Player' # 10 
) 

Sonra, örneğin, çalışma alanı 7. "${workspaceNames[7]}" adında ve verilen bir değişken i, çalışma alanı # i"${workspaceNames[i]}" adlandırılır.

+0

Bu çok iyi çalışıyor, ancak bu işlevin nasıl ortaya çıkacağını yanlış anlamış olmalıyım. Bu komut dosyasının amacı, her çalışma alanının adını, bilgiyi başka bir programa pipetleyerek grafiksel olarak göstermektir. Bu, şu anda her çalışma alanı adından geçer ve en son olarak görüntüler. Dizilerin nasıl çalıştığını gösterdiğiniz için teşekkür ederim, dizilerin nerede faydalı olabileceğini yazdığım küçük senaryolarda başka birçok durum var. Yanlış bilgiyi sormaktan çekinmediysem, sorgumda tek bir işlev yerine bütün betik içerdim. – Wulfre

+0

Sadece bunu anladığımdan emin olmak için '!' Değişkeninde bir değişken eklemek için kullanabilirsiniz! Daha önce sadece $ {workspace $ {i} Name} 'ı yapmaya çalışıyordum. – Wulfre

+0

@Wulfre: 'foo' değeri "bar" olan bir değişkense, "$ {! Foo}", $ {bar} 'ile eşdeğerdir. Buna * dolaylı genişleme * denir. Bkz. [* Bash Referans Kılavuzu *, §3.5.3 ”Kabuk Parametre Genişletme”] (http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion). – ruakh

1

Böyle bir şey, belki de?

workspaceCount=10 

while true; do 
    # Output will look like "%{c}$(workspace1Color)${separator}$(workspace2Color)${separator}...." 

    # This is what is sent before the first item in each line 
    itemSep="%{c}" 

    for i in {1..$workspaceCount}; do 

    if [ ${currentWorkspace} -eq $i ]; then 
     color="${green}" 
    elif [[ $(echo ${filledWorkspaces} | grep -w "1") == "" ]]; then 
     color="${grey}" 
    else 
     color="${foreground}" 
    fi 

    echo -n "${itemSep}${color}" 
    itemSep="${separator}" 

    done 
    echo # Send LF after all items 

done 
+0

Ayırıcıların nasıl çalıştığına dair fikir için teşekkür ederiz. Son cevabım için bu fikri çaldım. – Wulfre

0

ben kendi başıma geldi ruakh ve Phil Freed yanı sıra bir şey hem fikir kullanılarak istediğini elde etmek için bir yol buldum. Bu sorunu çözmek için en kısa veya en etkili yol olmayabilir, ancak 10 ayrı işleve sahip olmaktan çok daha kısadır. Yeni bir değişkenin sonuna tek fonksiyonunun çıktı olurdu ekleyerek 10 çalışma alanları ile Loop'ta:

#!/bin/bash 

# Include config file. 
. $(dirname $0)/config 

getWorkspaceInfo(){ 
    filledWorkspaces=$(i3-msg -t get_workspaces | grep -Po '"'"name"'"\s*:\s*"\K([^"]*)') 
    currentWorkspace=$(i3-msg -t get_outputs | sed 's/.*"current_workspace":"\([^"]*\)".*/\1/') 
} 

# Determine the status of each workspace. Current is green, unfocused is white, empty is grey. 
workspaces(){ 
    workspaces="" 
    currentSeparator="${separator}" 

    for i in {1..10} ; do 
     if [[ ${currentWorkspace} -eq ${i} ]]; then 
      color=${green} 
     elif [[ $(echo ${filledWorkspaces} | grep -w "${i}") == "" ]]; then 
      color=${grey} 
     else 
      color=${foreground} 
     fi 

     if [[ ${i} -eq 10 ]]; then 
      currentSeparator="" 
     fi 

     workspaces+="%{F$color}${workspaceNames[i]}${currentSeparator}" 
    done 

    echo "${workspaces}" 
} 

# Pipe functions to the bar infinitely. 
while true; do 
    getWorkspaceInfo 
    echo "%{c}$(workspaces)" 
done | lemonbar -g ${panelWidth}x${panelHeight}+${panelX}+${bottomPanelY} -f "${font}" -f "${iconFont}" -B "${background}" -F "${foreground}" -p -d | \ 
    while true; do read line; eval $line; done & 

mümkün olduğunca basit ne yaptığını açıklamak için. Artık her bir işlev çağrısı arasına bir ayırıcı ekleyemediğim için, ayırıcıyı eko sonuna ekledim, son çalışma alanına herhangi bir ayırıcı eklenmediğinden, ayırıcı değişkeni null olarak ayarlayan bir for döngüsü kullanmayın.

İlgili konular