You are not logged in.
In this case that `ls` only seems to be for determining whether the file exists. This is exactly what test's -e flag is for. Or potentially -b/-c/-d or -f depending on the limitations you'd like to place. That looks like LVM stuff with which I have no experience, so I'm not sure which would be best, but certainly even -e would be better than that ls check:
if [ -e "$FILE" ]; then
Also it looks like there are comments in there that aren't commented out.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
good catch i forgot that.
i had it when i was checking if a directory within the drive which i changed latter but missed that.
In this case that `ls` only seems to be for determining whether the file exists. This is exactly what test's -e flag is for. Or potentially -b/-c/-d or -f depending on the limitations you'd like to place. That looks like LVM stuff with which I have no experience, so I'm not sure which would be best, but certainly even -e would be better than that ls check:
if [ -e "$FILE" ]; then
Also it looks like there are comments in there that aren't commented out.
I went with the -f file its able to read the /dev/mapper/it file. though I guess -e would be better as a general rule for any type of file.
Last edited by bleach (2017-01-26 16:57:44)
Offline
You may also be interested in the "user" filesystem option, which allows an unprivileged user to mount the filesystem. An example from my fstab:
LABEL=Data /media/usb ext4 rw,lazytime,data=ordered,user,noauto,nofail 0 0
You can also add similar fstab lines for your various bind mounts. Naturally, you'd include "bind" in the options and could drop most of the others.
Offline
You may also be interested in the "user" filesystem option, which allows an unprivileged user to mount the filesystem. An example from my fstab:
LABEL=Data /media/usb ext4 rw,lazytime,data=ordered,user,noauto,nofail 0 0
You can also add similar fstab lines for your various bind mounts. Naturally, you'd include "bind" in the options and could drop most of the others.
that's normally a good idea but in this case i already have to use sudo for other things in this and i have a short time were sudo will be active without needing to enter it every time(though its just long enough), but definitely if I was just mounting also i use a filesystem that preserves user:groups.
Offline
Fair enough. Oh, by the way, you might *also* be interested to know that kill(1) can kill processes by name; it is only bash and zsh's builtin kill (which mask it unless you turn off their builtin) that can't. The builtins exist for hysterical raisins.
Offline
Get source/file with and without scripts run
source_urllib.py
http://pastebin.com/usRDFFtj
source_phant.sh
http://pastebin.com/cj7dG5zE
source_gtk_webkit.py
http://pastebin.com/igr4FLAA
source_PyQt4.py
http://pastebin.com/571gRVAR
source_PyQy5.py
http://pastebin.com/Qb0kmsYV
Offline
Simple m3u8 (Stream broken into segments) stream downloaders. They will get you a file.ts(MPEG-2 transport stream)
m3u8_dload.sh with bash and friends.
#! /usr/bin/env bash
#m3u8 stream downloader
#Works for m3u8 with complete url in segment list.
#User agent for requests
agent='Mozilla/5.0 (Windows NT 6.2; x86_64; rv:48.0) Gecko/20100101 Firefox/50.0'
#Display m3u8 and get inputs
read -p "Enter/paste m3u8 url: " m3u8_url
curl -s -A "$agent" "$m3u8_url"
read -p "Enter segment length in seconds: " seg_time
read -p "Enter output file name: " f_name
echo -e "\nYou are downloading:\n"$m3u8_url"\n\nCtrl + C to stop."
#Loop download segments in order, on time, to file.
while :; do
segs=$(curl -s -A "$agent" "$m3u8_url" -o - | grep ".ts")
for i in ${segs[@]}; do
sleep $seg_time &
curl -s -A "$agent" "$i" -o - >> "$f_name"
wait
done
done
m3u8_dload.py with python3 and urllib
#! /usr/bin/env python
#m3u8 stream downloader
#Works for m3u8 with complete url in segment list.
import urllib.request, time
#User agent for requests
user_agent = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; x86_64; rv:48.0)'
' Gecko/20100101 Firefox/50.0'}
#Loop download segments in order, on time, to file.
def get_ts(m3u8_req, seg_time, f_name):
with open(f_name, 'ab') as tsfile:
while True:
start = time.time()
with urllib.request.urlopen(m3u8_req) as f:
for line in f:
if 'ts' in str(line):
segs = str(line.strip()).split("'")[1]
req = urllib.request.Request(segs, data=None,
headers=user_agent)
tsfile.write(urllib.request.urlopen(req).read())
time.sleep(seg_time - (time.time() - start) % seg_time)
#Display m3u8 and get inputs
def main():
url = input('Enter m3u8 url: ')
m3u8_req = urllib.request.Request(url, data=None, headers=user_agent)
with urllib.request.urlopen(m3u8_req) as m3u8_playlist:
for line in m3u8_playlist:
print (str(line.strip()).split("'")[1])
seg_time = int(input('Enter segment length in seconds: '))
f_name = input('Enter output file name: ')
print ('\nYou are downloading:\n', url, '\n\nCtrl + C to stop')
get_ts(m3u8_req, seg_time, f_name)
main()
Run that through ffmpeg when you are done if you want a different format and a file header on it.
Audio example:
ffmpeg -i file.ts -vn -c:a copy file.m4a
Offline
Run process exactly every x seconds regardless of process run time.
#! /usr/bin/env python
#Example: looping exactly every x seconds, with variable timed processes.
import time, datetime, random, decimal
#Random number generator for simulation
def random_num_gen():
ran_num = decimal.Decimal(str(random.random()))
return ran_num
#Function loops every 3 seconds regardless of process run times
def test(num):
#Get start time for loop
start = time.time()
#Run loop 5 times
for loop in range(1, 6):
#Get datetime to print for simulation
now = datetime.datetime.now()
#Variable timed processes simulation
print ('\n'+'Running 1st process for', num, 'second')
time.sleep(num)
print ('Running 2nd process for', num, 'seconds')
time.sleep(num)
print ('Running 3rd process for', num, 'seconds')
time.sleep(num)
print ((loop), '| 3 sec. loop time: >', (now), '\n',
'......waiting for timer......')
#Sleep start time + 3 seconds
time.sleep(3.0 - (time.time() - start) % 3.0)
#Get new random decimal number for next loop
num = random_num_gen()
def main():
#Get random decimal number to start
num = random_num_gen()
#Run the function
test(num)
main()
Offline
Going by the description...
watch -n 1 timeout 1 foo
Last edited by Alad (2017-01-28 18:06:17)
Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby
Offline
You would have to call a subprocess from python for watch.
subprocess.Popen([watch...
Same for sleep
subprocess.Popen(['sleep', '3'])
It was meant to be a python way within a python script without having to call a bash subprocess, to explain post #2907
Thanks for the post about watch
Offline
Web browser independent Qt5 web inspector.
Needs qt5-base qt5-webkit python-pyqt5 pyqt5-common
#!/usr/bin/env python
#Qt5 webkit inspector
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtWebKitWidgets import QWebPage, QWebView, QWebInspector
#Change user agent here
agent = ('Mozilla/5.0 (Windows NT 6.2; x86_64; rv:48.0)'
' Gecko/20100101 Firefox/50.0')
class InspWindow(QMainWindow):
def __init__(self, url):
super(InspWindow, self).__init__()
#User agent for requests
user_agent = QWebPage()
user_agent.userAgentForUrl = lambda x: (agent)
self.view = QWebView(self)
self.view.setPage(user_agent)
self.view.setUrl(url)
self.view.settings().setAttribute(
QWebSettings.DeveloperExtrasEnabled, True)
#Load scripts - images - plugins
self.view.settings().setAttribute(
QWebSettings.JavascriptEnabled, False)
self.view.settings().setAttribute(
QWebSettings.AutoLoadImages, False)
self.view.settings().setAttribute(
QWebSettings.PluginsEnabled, True)
self.view.settings().globalSettings().setFontSize(
QWebSettings.MinimumFontSize, 20)
#Open inspector to page
self.inspector = QWebInspector()
self.inspector.resize(1400, 900)
self.inspector.setPage(self.view.page())
self.inspector.show()
if __name__ == '__main__':
app = QApplication([])
if len(sys.argv) > 1:
url = QUrl(sys.argv[1])
else:
url = QUrl(input("Enter url to inspect: "))
insp = InspWindow(url)
sys.exit(app.exec_())
Offline
Clean orphans and pacman cache
#!/bin/bash
select ops in "clean orphans" "clean cache" exit ; do
case $ops in
"clean orphans")
[[ -n $(pacman -Qdt) ]] && sudo pacman -Rsn $(pacman -Qdtq) || echo "no orphans to remove"
;;
"clean cache")
# remove all uninstalled packages
paccache -ruk0
# remove all cached versions of all packages except latest 3
paccache -r
;;
exit)
echo "bye" && break
;;
esac
done
Arch is home!
https://github.com/Docbroke
Offline
I am currently tinkering with i3wm. Occasionally, I am looking for a new shortcut to assign, or simply forget which is which. I am also playing a bit with python, just for the sake of learning new stuff. I wrote this little script to parse the current config file (as per the man page) and display a helpful GTK3 window with all the shortcuts.
.config/i3/config
$mod+Shift+h exec python ~/bin/i3wm_help.py
~/bin/i3wm_help.py
"""
Parse the i3 config file, collect and parse shortcuts and display on screen
"""
import string
import os
import gi
import collections
gi.require_version('Gtk','3.0')
from gi.repository import Gtk
class CellRendererTextWindow(Gtk.Window):
def __init__(self,dict_config, path):
Gtk.Window.__init__(self, title='Help ' + path)
self.set_border_width(10)
self.grid = Gtk.Grid()
self.grid.set_column_homogeneous(True)
self.grid.set_row_homogeneous(True)
self.add(self.grid)
hbox = Gtk.Box(spacing=6)
self.add(hbox)
self.set_default_size(1120,720)
self.liststore = Gtk.ListStore(str,str)
for sc, dscrptn in dict_config.items():
self.liststore.append([sc, dscrptn])
treeview = Gtk.TreeView(model=self.liststore)
sct = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn('Shortcut', sct, text=0)
treeview.append_column(column_text)
dtext = Gtk.CellRendererText()
desc_column_text = Gtk.TreeViewColumn('Description', dtext, text=1)
treeview.append_column(desc_column_text)
self.add(treeview)
button = Gtk.Button('Close')
button.connect('clicked', self.on_close_clicked)
self.scrollable_treelist = Gtk.ScrolledWindow()
self.scrollable_treelist.set_vexpand(True)
self.grid.attach(self.scrollable_treelist, 0, 0, 12, 16)
self.grid.attach_next_to(button, self.scrollable_treelist,
Gtk.PositionType.BOTTOM, 1, 1)
self.scrollable_treelist.add(treeview)
self.show_all()
def on_close_clicked(self, button):
Gtk.main_quit()
""" possible config file paths as per the i3 man page """
def getConfigPath():
paths = ['~/.config/i3/config',
'/etc/xdg/i3/config',
'~/.i3/config',
'/etc/i3/config']
configpath = False
for my_path in paths:
tmp_path = os.path.expanduser(my_path)
if os.path.isfile(tmp_path):
configpath = tmp_path
break
return configpath
"""
Open the path as found in getConfigPath and parse the shortcuts into a
dictionary
attributes config_path the full path to the config file
"""
def parseConfigFile(config_path):
myshortcuts = {}
myvars = {}
with open(config_path, encoding='utf-8') as my_file:
for my_line in my_file:
words = my_line.split(' ')
if words[0] == 'set' and words[1].startswith('$'):
myvars[words[1]] = ' '.join(words[2:]).rstrip()
elif words[0] == 'bindsym':
pos = 1
if words[1].startswith('--'):
pos = 2
tmpkeys = words[pos].split('+')
for pos, subkey in enumerate(tmpkeys):
if subkey.startswith('$'):
tmpkeys[pos] = myvars[subkey]
key = '+'.join(tmpkeys)
myshortcuts[key] = ' '.join(words[2:]).rstrip()
return myshortcuts
"""
Sort the config dictionary by shortcut
TODO: Mod+foo and Mod+Shift+Foo should be grouped
"""
def sortbyshortcut(dcfg):
return collections.OrderedDict(sorted(dcfg.items()))
current_config_path = getConfigPath()
if current_config_path == False:
print('No i3wm configuration file was found')
""" TODO Better error handling"""
else:
myconfig = parseConfigFile(current_config_path)
myconfig = sortbyshortcut(myconfig)
print(myconfig)
win = CellRendererTextWindow(myconfig, current_config_path)
win.connect('delete-event', Gtk.main_quit)
win.show_all()
Gtk.main()
Geek, runner, motorcyclist and professional know-it-all
Offline
Just a tool to use usbip a little easier and attach usb devices to my remote upboards rpi's etc.
How to use the scripts.
Install usbip on both server & client.
Put the scripts somewhere on server & client.
On the client, create dir. ~/.scripts/usbip-client, or change the paths.
Edit the variables in both scripts and your set to go.
I know next to nothing about the security of usbip and thus run the tool tunneled.
Because I already use SSH, the 'busid', which is also needed on the client, is scp'd to it
If you wish, you can automate the 'atach' option. To do so, setup a ssh user
that only runs the client script, by prepending the command to the key.
If you know of a neat trick to send a 'signoff' to the usbip daemon, that unbind
could be automated, too, oh and please let me know, thanks.
command cycle
ssh -R 3240:localhost:3240 user@remote_host
sh usbip-server bind (server)
sh usbip-client atach (client)
You can do your foo now (client)
sh usbip-client dtach (client)
sh usbip-server ubind (server)
quit ssh
A little warning:
Be carefull editing the scripts, you may hang the process client and/or ssh.
If you bind a device be sure nothing is using it, beside a disk, on the host.
A usb disk will unmount and than bind automatic, bluetooth f.i. does not.
You may even end up with unresponsive machines (both), I have warned you.
Your admin/company may not be amused, if you use this, should ask first.
I'm open to suggestions, improvements and the like.
The server part:
#!/bin/bash
## usbip daemon script see: man (8) usbipd
set -x
## Change scpaddr & where to store the busid on the client
SCP_ADDRESS() {
scpadr='mark@172.16.2.6:.scripts/usbip-client'
}
on_exit() {
local exit_status=${1:-$?}
echo Exit "$0" with "$exit_status"
exit "$exit_status"
}
trap on_exit 0 1 2 3 15
busids=$(busids 2>/dev/null) || busids=/tmp/busids
## Bind usb to usbip
if [[ $1 == bind ]]; then
if [[ -e "$busids" ]]; then
printf "%s\n" "busids exists, run option ubind, bailing"
exit 1
fi
## if off, turn usbip daemon on
#if [[ ! root == $(ps -ef|grep usbipd|awk -F ''$USER'| ' '{print $1}') ]]; then
if [[ ! usbipd == $(pgrep -l usbipd|awk -F ' ' '{print $2}') ]]; then
sudo usbipd -4 -D
fi
## List driver assignments for usb devices.
sudo usbip list --local
busid=""
while [[ ! $busid =~ ^[0-9-]+$ ]]; do
#echo fill in a busid
read -p "enter busid (example: 1-2) : " busid
done
## Need the busids, for the server & client
echo "$busid" > "$busids"
## Bind usbip-host.ko to the device of busid 1-2(example)
sudo usbip bind --busid="$(<"$busids")"
## Secure copy busids to the client for a little automation
SCP_ADDRESS
scp "$busids" "$scpadr"
## Unbind usb device from usbip
elif [[ $1 == ubind ]]; then
if [[ -e "$busids" ]]; then
sudo usbip unbind --busid="$(<$busids)"
rm -f "$busids"
else
printf "%s\n" "Nothing to unbind"
#exit 1
fi
## need some option
else
printf "%s\n" "Usage: sh usbip-server [bind] [ubind]"
fi
#on_exit
# vim:set ts=2 sw=2 et:
The client part:
#!/bin/bash
## usbip client script see: man (8) usbip
set -x
## Change the next 3 variables, 'busid' 'mnt' & 'mntpnt', change 'rem' if not running trough a tunnel.
BUSID() {
busid=$(<~/.scripts/usbip-client/busids) ## where the busid file is stored
}
MOUNT() {
mnt='/dev/disk/by-uuid/<your-attached-device-uuid' ## what to mount, if a disk
}
MOUNTPOINT() {
mntpnt='/mnt/usbip' ## where to mount, if device is a usb disk
}
REMOTE() {
rem='127.0.0.1' ## Address, change to IP of remote daemon, if not a tunnel
}
on_exit() {
local exit_status=${1:-$?}
echo Exit "$0" with "$exit_status"
exit "$exit_status"
}
trap on_exit 0 1 2 3 15
## Attach remote device to client
if [[ $1 == atach ]]; then
mod=$(lsmod|grep vhci_hcd|awk -F ' ' '{print $1}')
if [[ -z "$mod" ]]; then
printf "%s\n" "Warning: No vci-hcd module, modprobe vhci-hcd"
sudo modprobe vhci-hcd
fi
REMOTE
remote="$(sudo usbip list --remote=$rem|grep $rem)"
if [[ -z "$remote" ]]; then
printf "%s\n" "Error: No remote device found, start your daemon, remote tunnel or rebind"
exit 1
fi
BUSID
if [[ -z "$busid" ]]; then
printf "%s\n" "Error: no busid found, not able to attach"
exit 1
else
sudo usbip attach --remote="$rem" --busid="$busid"
fi
sleep 5 ## Need this on a RPI, if mount is executed
MOUNT
MOUNTPOINT
if [[ -b "$mnt" ]]; then
sudo mount "$mnt" "$mntpnt"
printf "%s\n" "mounted $mnt on $mntpnt"
fi
## Detach remote device from client
elif [[ $1 == dtach ]]; then
## If the device was a disk, unmount it
MOUNTPOINT
if grep -qs "$mntpnt" /proc/mounts; then
sudo umount "$mntpnt"
printf "%s\n" "Unmounted $mntpnt"
fi
port="$(sudo usbip port|grep Port|awk -F ' |:' '{print $2}')"
if [[ -z $port ]]; then
printf "%s\n" "Nothing to detach"
else
sudo usbip detach --port="$port"
## If the next rm is enabled you need to use usbip cmd or rebind daemon
#rm -f ~/.scripts/usbip-client/busids
printf "%s\n" "Port $port detached, you can unbind the daemon"
fi
## Need an option
else
printf "%s\n" "Usage: sh usbip [atach] [dtach]"
fi
# vim:set ts=2 sw=2 et:
Offline
Libinput somehow doesn't read the conf file, cus i coulnd't fix it, just wrote a script to do it manually at startup..
conx.sh
#!/bin/bash
line=$(xinput list | grep -i "ETPS/2 Elantech Touchpad") #name of the touchpad
number=${line:50:2}
echo "Touchpad is "$number
xoutput=$(xinput list-props $number)
xoutput=$(xinput list-props $number | grep -i "libinput Natural Scrolling Enabled (" )
functionNumber=$(echo $xoutput | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//')
echo "Nat Scroll is "$functionNumber
xinput set-prop $number $functionNumber 0
xoutput=$(xinput list-props $number | grep -i "libinput Tapping Enabled (" )
functionNumber=$(echo $xoutput | grep -o -E '[0-9]+' | head -1) # | sed -e 's/^0\+//')
echo "Tapping is "$functionNumber
xinput set-prop $number $functionNumber 1
Offline
That's a ridiculous number of subshells, variables, and echoing for no purpose. For example, the following are equivalent:
line=$(xinput list | grep -i "ETPS/2 Elantech Touchpad") #name of the touchpad
number=${line:50:2}
echo "Touchpad is "$number
xoutput=$(xinput list-props $number)
xinput list-props $number | grep ...
xinput list-props "ETPS/2 Elantech Touchpad" | grep ...
Also you're burrying grep output in variables only to echo the variable and pass it through grep again, or sed, or head. "grep -m1 <pattern>" is the same as "grep <pattern> | head -1" but with one fewer process and a lot less work for grep to do.
I have no idea what that is all supposed to do, but I bet it could be done with at most 2 calls to xinput with a single awk command between them.
EDIT: scratch that, two calls to xinput will do it
xinput --set-prop "ETPS/2 Elantech Touchpad" "libinput Natural Scrolling Enabled" 0
xinput --set-prop "ETPS/2 Elantech Touchpad" "libinput Tapping Enabled" 1
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
On the topic of xinput --set-prop, it would be really nice to have a script or bash alias that *always* grabs the correct ID for my touchpad:
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Logitech G500 id=9 [slave pointer (2)]
⎜ ↳ Logitech G500 id=10 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=13 [slave pointer (2)]
...
Currently ID 13, but that can change if I reboot without my mouse being plugged in, for example. I've once managed to accidentally disable the keyboard as a result of that id changing... But it happens so rarely (my mouse is 95% of the time plugged in at boot) that im not really in the mood to bother exploring the possibility of changing my alias at this time.
EDIT: The alias, in case anyone's curious:
alias touchpadoff='xinput set-prop 13 "Device Enabled" 0'
alias touchpadon='xinput set-prop 13 "Device Enabled" 1'
Last edited by JohnBobSmith (2017-02-16 04:21:25)
I am diagnosed with bipolar disorder. As it turns out, what I thought was my greatest weakness is now my greatest strength.
Everyday, I make a conscious choice to overcome my challenges and my problems. It's not easy, but its better than the alternative...
Offline
JBS, did you read my post at all. I don't know why people jump through hoops to figure out a dynamic ID number assigned to devices when they have names.
device can be the device name as a string or the XID of the device.
Just use the name.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
How I managed to miss that the first time is completely beyond me... Thanks though! This helps a lot.
I am diagnosed with bipolar disorder. As it turns out, what I thought was my greatest weakness is now my greatest strength.
Everyday, I make a conscious choice to overcome my challenges and my problems. It's not easy, but its better than the alternative...
Offline
This is pmenu based wrapper around pass (password manager). This script can be adapted for use with dmenu or rofi, however for terminal use I have opted for pmenu.
#!/usr/bin/env bash
## Run this script from terminal or bind it to a key as something like "sakura -eh passmenu"
## assumes working pass installation with password store in ~/.password-store (default)
## the script depends on pmenu
shopt -s nullglob globstar lastpipe
prefix=${PASSWORD_STORE_DIR-~/.password-store}
password_files=( "$prefix"/**/*.gpg )
password_files=( "${password_files[@]#"$prefix"/}" )
password_files=( "${password_files[@]%.gpg}" )
echo -e "password view\ngoogle otp\npassword edit\nnew password\nremove password" | pmenu -p SELECT: | read ops
case $ops in
password\ view) pass show $(printf '%s\n' "${password_files[@]}" | pmenu -p PASSWORD_VIEW:) ;;
password\ edit) pass edit $(printf '%s\n' "${password_files[@]}" | pmenu -p PASSWORD_EDIT:) ;;
new\ password) pass edit $(cat /dev/null | pmenu -p NEW_PASSWORD:) ;;
remove\ password) pass rm $(printf '%s\n' "${password_files[@]}" | pmenu -p REMOVE_PASSWORD:) ;;
esac
Arch is home!
https://github.com/Docbroke
Offline
I got tired of looking up how to do this (pactl wrapper).
Redirect an application's audio to specified output.
/usr/local/sbin/pulse.out
#!/bin/bash
if [ -n "${1}" ] && [ -n "${2}" ]; then
#CLI: $0 processname output
app=$1
out=$2
appstream=$(echo $(pactl list sink-inputs | grep -e "Sink\ Input" -e "application.process.binary") | grep -o "Sink\ Input\ #[0-9]*\ application\.process\.binary\ =\ \"$app\"" | sed -e 's/^.*#//' -e 's/\ .*//')
else
#hotkey+pointer interface (xprop, zenity): Click window, choose output
app=$(xprop | grep _NET_WM_PID | grep -o [0-9]*)
out=$(zenity --list --radiolist --text "Set audio output for window:" --column "Select" --column "Output" FALSE "surround" FALSE "bluetooth" FALSE "headset" )
appstream=$(echo $(pactl list sink-inputs | grep -e "Sink\ Input" -e "application.process.id") | grep -o "Sink\ Input\ #[0-9]*\ application\.process\.id\ =\ \"$app\"" | sed -e 's/^.*#//' -e 's/\ .*//')
fi
case "$out" in
default|speakers|system|pa|surround|5.1)
output="alsa_output.pci-0000_00_1b.0.iec958-ac3-surround-51.equalizer"
;;
bluetooth|YBS-02|ybs-02|ybs02)
output="bluez_sink.FC_58_FA_B7_22_0C.a2dp_sink"
;;
headset|DR-BT101|dr-bt101|drbt101)
output="bluez_sink.00_1F_82_28_93_51.a2dp_sink"
;;
esac
[[ $output ]] && for i in $appstream; do \
pactl move-sink-input $i $output; done
pulse.out firefox bluetooth
pulse.out mpv surround
Or set "pulse.out" to a hotkey and click on the window to redirect audio from.
Get your own sink names!
pactl list sinks | grep -C 2 Name
Last edited by quequotion (2020-05-10 07:54:03)
makepkg-optimize · indicator-powersave · pantheon-{3d,lite} · {pantheon,higan}-qq
Offline
With xbacklight failing with modesetting driver, I have to find a workaround. Here is my backlight script, with added advantage, it works with console.
#!/bin/bash
#max=4882
increase() {
if [[ $(cat /sys/class/backlight/intel_backlight/brightness) -le 4600 ]]; then
sudo tee /sys/class/backlight/intel_backlight/brightness <<< $(echo $(($(cat /sys/class/backlight/intel_backlight/brightness) + 200)))
else
[ -n "$DISPLAY" ] && notify-send -u critical "Backlight at maximum" || echo "Backlight at maximum"
fi
}
decrease() {
if [[ $(cat /sys/class/backlight/intel_backlight/brightness) -ge 1600 ]]; then
sudo tee /sys/class/backlight/intel_backlight/brightness <<< $(echo $(($(cat /sys/class/backlight/intel_backlight/brightness) - 200)))
else
[ -n "$DISPLAY" ] && notify-send -u critical "Backlight at minimum" || echo "Backlight at minimum"
fi
}
case $1 in
check) cat /sys/class/backlight/intel_backlight/brightness ;;
up) increase ;;
down) decrease ;;
*)
echo "USAGE: $0 check/up/down"
;;
esac
I have this script bound to my brightness keys as
backlight up && notify-send "$(backlight check)"
and similarly backlight down.
Arch is home!
https://github.com/Docbroke
Offline
It's odd to use the test binary [ in some places and bash's built in [[ others. Also, there's no need to have a case statement just to call functions of names similar (but oddly not the same) as the parameter names. Just call your functions 'up' and 'down' and make one for 'check', then after the function definitions:
${1:-check} 2>/dev/null || echo "USAGE: $0 [ check | up | down ]"
You might also just want to retrieve the current value once rather than abusing cats.
Also, why do you call the script twice in your key binding? It outputs the value after a change, so just send the output to notify send. Further, you have notify send in the script already, so put that in one place or the other, not both. Consider this:
#!/bin/bash
base=/sys/class/backlight/intel_backlight
cur=$(<$base/brightness)
max=$(<$base/max_brightness)
min=1600
step=200
case $1 in
up|increase|+) cur=$(($cur + $step)) ;;
down|decrease|-) cur=$(($cur - $step)) ;;
check) ;;
*) echo "USAGE: $0 [ up | down | check ]"; exit 1 ;;
esac
[[ $cur -gt $max ]] && echo "Backlight at Maximum" && exit 1
[[ $cur -lt $min ]] && echo "Backlight at Minimum" && exit 1
echo $cur | sudo tee $base/brightness
Then your binding would be "notify-send $(backlight up)" for example.
(No cats were harmed in the production of this script).
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Wonderful
I would have never thought of using case to define variables.
Arch is home!
https://github.com/Docbroke
Offline
I needed to update old fstab and crypttab entries to UUID the other day and ended up writing a script to automate part of the process: fstab-uuid. It will print updated entries to STDOUT that you can then judiciously paste into the file after inspection. Obviously some entries should be discarded (such as UUID entries for non-persistent, random-key encrypted swap partitions).
I have also added a scan mode to help update non-fstab files. It will naïvely scan a file in text mode for plaintext matches to paths that can be replaced with a UUID. Matching lines will be printed along with the matched path and corresponding UUID. It's useful for updating e.g. bootloaders and mount scripts.
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline