Shell命令不起作用

时间:2017-02-01 23:32:36

标签: shell if-statement

我在我的i3config文件中使用volnoti,一个通知服务,以及我的i3窗口管理器,我试图像这样实现volnoti的命令:

# Pulse Audio controls
# Increase sound volume
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 1 +5% && pkill -RTMIN+1 i3blocks && volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*')
# Decrease sound volume
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 1 -5% && pkill -RTMIN+1 i3blocks && volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*')
# Mute sound
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 1 toggle && pkill -RTMIN+1 i3blocks && if [[ -n $(amixer -c 1 -M -D pulse get Master | grep '\[off\]' -m 1) ]]; then volnoti-show -m; else volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*'); fi

显示增加和减少没有问题,但如果我静音,i3会记录此错误:

ERROR: Could not translate string to key symbol: "split+h"
[libi3] ERROR: Surface 0x555ee0dfd3b0 is not initialized, skipping drawing.
[libi3] ERROR: Surface 0x555ee0dfd3b0 is not initialized, skipping drawing.
[libi3] ERROR: Surface 0x555ee0dfd3b0 is not initialized, skipping drawing.
ERROR: Received ConfigureNotify for unknown window 0x00800000
ERROR: Received ExposeEvent for unknown window 0x00800000
ERROR: Received ConfigureNotify for unknown window 0x00800000
ERROR: Received ConfigureNotify for unknown window 0x00800003
ERROR: Received ConfigureNotify for unknown window 0x00800003
ERROR: Received ConfigureNotify for unknown window 0x00800006
ERROR: Received ConfigureNotify for unknown window 0x00800006
ERROR: Received ConfigureNotify for unknown window 0x00800009
ERROR: Received ConfigureNotify for unknown window 0x00800009
ERROR: Received ConfigureNotify for unknown window 0x0080000c
ERROR: Received ConfigureNotify for unknown window 0x0080000c
ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'shmlog', 'debuglog', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'sticky', 'split', 'floating', 'mark', 'unmark', 'resize', 'rename', 'nop', 'scratchpad', 'title_format', 'mode', 'bar'
ERROR: Your command: exec --no-startup-id pactl set-sink-mute 1 toggle && pkill -RTMIN+1 i3blocks && "if [[ -n $(amixer -c 1 -M -D pulse get Master | grep '\[off\]' -m 1) ]]; then volnoti-show -m; else volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*'); fi"
ERROR:                                                                                                                                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我不得不承认,这不是最优雅的解决方案。但除了最后一行之外,它还在工作。如果我直接在终端中执行最后一部分,它可以正常工作并且可以正确检测静音:

if  [[ -n $(amixer -c 1 -M -D pulse get Master | grep '\[off\]' -m 1) ]]; then volnoti-show -m; else volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*'); fi

1 个答案:

答案 0 :(得分:1)

i3 配置中使用复杂的shell命令时存在很多缺陷。 i3 使用某些特殊字符作为语法元素,但不提供引用它们的全功能方法。在这种情况下, i3 ;解释为 i3 命令分隔符,并期望它后跟一个 i3 命令,{ {1}}不是。

您可以尝试将完整的命令部分放在双引号内,例如

then

这可能有效,也可能无效。 (并且在错误消息中,您似乎已经尝试引用命令的一部分)

解决此类问题的更好方法通常是将shell代码放入脚本中,然后将其绑定到快捷方式。

脚本,例如bindsym XF86AudioMute exec --no-startup-id "pactl set-sink-mute 1 toggle && pkill -RTMIN+1 i3blocks && if [[ -n $(amixer -c 1 -M -D pulse get Master | grep '\[off\]' -m 1) ]]; then volnoti-show -m; else volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*'); fi"

volcontrol.sh

i3 config

#!/bin/sh
# Pulse Audio controls
case $1 in
  raise)
    # Increase sound volume
    pactl set-sink-volume 1 +5% && pkill -RTMIN+1 i3blocks && volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*')
    ;;
  lower)
    # Decrease sound volume
    pactl set-sink-volume 1 -5% && pkill -RTMIN+1 i3blocks && volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*')
    ;;
  mute)
    # Mute sound
    pactl set-sink-mute 1 toggle && pkill -RTMIN+1 i3blocks && if [[ -n $(amixer -c 1 -M -D pulse get Master | grep '\[off\]' -m 1) ]]; then volnoti-show -m; else volnoti-show $(amixer -c 1 -M -D pulse get Master | grep -o '[0-9]*%' -m 1 | grep -o '[0-9]*'); fi
    ;;
esac

这避免了 i3 对配置设置的shell代码产生误解的所有问题,因此可以提供更大的灵活性,尤其是在链接多个shell命令或使用更复杂的shell结构时。