2016-04-03 6 views
1

Ich versuche, Informationen aus meinen Arbeitsbereichen in einen anderen Befehl zu leiten, und weil jeder Arbeitsbereich die gleichen Informationen enthält, mit nur einer anderen Nummer, um ihn zu identifizieren, habe ich 10 Funktionen geschrieben, wobei der einzige Unterschied ein Zeichen in einigen Variablennamen ist. Ich habe das Gefühl, dass dies stark vereinfacht werden kann, aber ich kann mir nicht vorstellen, wie man in meiner Situation irgendeine Art von Schleife funktioniert.Möglich, 10 ähnliche Funktionen in eine for-Schleife zu verwandeln?

hier mein Skript ist die 10 Funktionen enthalten:

#!/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 & 

Hier ist die Konfigurationsdatei, die ich importieren bin:

#!/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

Muss Ihre Funktion tatsächlich die globale Variable 'workspace1color' setzen? Wie in - gibt es einen späteren Code, nachdem die Funktion aufgerufen wurde, die die 'workspace1color' verwenden muss, die die Funktion gesetzt hat? – ruakh

+0

Nein, die letzte Zeile des Skripts, die nach der Deklaration aller Funktionen kommt, ruft sie einfach alle auf und leitet dann die Ausgabe. – Wulfre

+0

Sie können eine Menge langsamer Prozesse speichern, um unnötige Verwendungen von 'cat' zu vermeiden:' rot = $ (grep -i color9 $ xres | tail -c 8) '. Als nächstes ist 'grep | awk 'ein * anti-pattern *, weil awk grep eingebaut hat:' xrandr | awk '/ Bildschirm 0/{Drucken $ 8}' '. – Jens

Antwort

4

Nun, die einfachste Lösung ist, wie etwas zu schreiben:

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 
} 

. . . Sie sollten jedoch in Erwägung ziehen, stattdessen Arrays zu verwenden. Zum Beispiel:

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 
) 

Dann zum Beispiel, Arbeitsplatz # 7 "${workspaceNames[7]}" genannt, und da eine Variable i, Arbeitsplatz # i ist "${workspaceNames[i]}" genannt.

+0

Das funktioniert sehr gut, aber ich muss missverstanden haben, wie sich diese Funktion ergeben hätte. Der Sinn dieses Skripts besteht darin, den Namen jedes Arbeitsbereichs grafisch darzustellen, indem die Informationen an ein anderes Programm weitergeleitet werden. Dies durchläuft derzeit jeden Arbeitsbereichnamen und zeigt ihn über den letzten an. Danke, dass Sie mir zeigen, wie Arrays funktionieren, es gibt viele andere Situationen in kleinen Skripten, die ich geschrieben habe, wo Arrays auch nützlich gewesen wären. Ich habe das gesamte Skript und nicht eine Funktion in meine Frage aufgenommen, wenn ich Sie nicht desinteressiert habe, indem ich nach der falschen Information gefragt habe. – Wulfre

+0

Um sicherzustellen, dass ich das verstehe, können Sie '!' Verwenden, um eine Variable in eine Variable einzufügen? Zuvor wollte ich nur '$ {workspace $ {i} Name}' machen. – Wulfre

+0

@Wulfre: Wenn 'foo' eine Variable ist, deren Wert 'bar' ist, dann ist' $ {! Foo} 'äquivalent zu' $ {bar} '. Dies wird * indirekte Erweiterung * genannt. Siehe [das * Bash-Referenzhandbuch *, §3.5.3 "Shell-Parametererweiterung"] (http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion). – ruakh

1

So etwas vielleicht?

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

Vielen Dank für die Idee, wie Separatoren funktionieren. Ich habe diese Idee für meine letzte Antwort gestohlen. – Wulfre

0

dachte ich, um einen Ausweg zu bekommen, was ich beide mit Ideen von ruakh und Phil Freed sowie etwas kam ich mit auf meinem eigenen wollte. Dies ist möglicherweise nicht der kürzeste oder effizienteste Weg, um das Problem zu lösen, aber es ist viel kürzer als 10 separate Funktionen.

#!/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 & 

Um zu erklären, was es so einfach wie möglich macht: Schleife durch alle 10 Arbeitsbereiche, und fügt hinzu, was mit dem Ende einer neuen Variable die Ausgabe einer einzelnen Funktion gewesen wäre. Da ich zwischen jedem Funktionsaufruf kein Trennzeichen mehr hinzufügen kann, fügte ich einfach das Trennzeichen am Ende des Echos ein und stellte sicher, dass dem letzten Arbeitsbereich kein Trennzeichen hinzugefügt wurde, indem eine for-Schleife verwendet wurde, die die Trennzeichenvariable auf null setzt.

Verwandte Themen