Команда nohup budgie-panel --replace&
. (Это для текущей версии № 10, GTK :будущая версия 11 , как говорят, будет основана на qt --, и это будет другая история.)
Чтобы вызвать это одним или двумя щелчками мыши, используйте ярлык -или добавьте средство запуска -с помощью gedit
:
.
gedit ~/.local/share/applications/restart-budgie.desktop
, затем вставьте строки ниже -и сохраните:
[Desktop Entry]
Type=Application
Name=Restart budgie desktop
Icon=preferences-desktop
Categories=System;Settings;
Exec=sh -c 'nohup budgie-panel --replace&'
Вы вводите свою функцию в одной строке. Строка будет строкой 1 2 3 4
, которая расширяется до "${integers[*]}"
со значением по умолчанию $IFS
. Вся эта единственная строка будет прочитана при первом вызове read
в arg
и использована (без кавычек )при вызове вашей функции. Поскольку $arg
не заключен в кавычки, оболочка будет плевать строку на пробелы, и ваша функция будет использовать только этот начальный 1
, который не является четным. Это означает, что echo $arg
не срабатывает.
Вместо:
#!/bin/bash
is_even () { (( $1 % 2 == 0 )) ;}
filter () {
local function_to_apply="$1"
local arg
while read -r arg; do
"$function_to_apply" "$arg" && echo "$arg"
done
}
integers=( 1 2 3 4 )
result=$(printf '%s\n' "${integers[@]}" | filter is_even)
declare -p result
Главное здесь — вывести элементы массива на отдельные строки в функцию filter
.
Это даст вам единственную строку 2\n4
(, где \n
— новая строка ). Это не должно быть сюрпризом, поскольку вы присваиваете строку result
.
Если вы хотите вернуть массив, вы можете сделать это в последнем выпускеbash
:
#!/bin/bash
is_even () { (( $1 % 2 == 0 )) ;}
filter () {
local func="$1"
local -n in_array="$2"
local -n out_array="$3"
local element
out_array=()
for element in "${in_array[@]}"; do
if "$func" "$element"; then
out_array+=( "$element" )
fi
done
}
integers=( 1 2 3 4 )
even_ints=()
filter is_even integers even_ints
declare -p even_ints
Здесь используются две переменные ссылки на имя внутри функции filter
. Первый — это входной массив, а второй — выходной массив.
Это даст вам результат
declare -a even_ints=([0]="2" [1]="4")
Другой способ передать значения в функцию filter
, очевидно, состоит в том, чтобы передать их в командной строке функции:
#!/bin/bash
is_even () { (( $1 % 2 == 0 )) ;}
filter () {
local func="$1"
local -n out_array="$2"
shift 2
local element
out_array=()
for element do
if "$func" "$element"; then
out_array+=( "$element" )
fi
done
}
integers=( 1 2 3 4 )
even_ints=()
filter is_even even_ints "${integers[@]}"
declare -p even_ints
1. @Kusalananda's filter
не сможет фильтровать массив на месте; если один и тот же массив указан как источник и место назначения, он просто усекает его.
Это можно легко исправить, переписав функцию следующим образом:
filter() {
local cb=$1 i j a; local -n src=$2 dst=$3
for a in "${src[@]}"; do
"$cb" "$a" && dst[i++]=$a
done
for((j=${#dst[@]}; j>=i; j--)); do
unset dst[j]
done
}
2. Однако такие демонстрации/вызовы (, например, "Как сделать функциональное программирование в bash" )совершенно бессмысленны . Даже по сравнению с другими языками очень высокого -уровня, такими как perl или javascript, bash невероятно медленный. Использование bash для разбора/фильтрации данных вместо вызова других утилит вроде grep
может оказаться на порядки медленнее.
Используя проблему из вопроса, решение grep будет в 3 раза быстрее даже с ничтожным массивом из 1000 -элементов и при фильтрации собственных массивов bash , а не некоторых внешних файлов. И это несмотря на то, что нужно разветвить около 3 процессов и выполнить внешний двоичный файл. См. приведенный ниже пример (с использованием массива из 100 000 элементов ):
.bash filter.sh 100000
=== bash_filter ===
real 0m1.037s
user 0m1.036s
sys 0m0.001s
=== grep_filter ===
real 0m0.302s
user 0m0.226s
sys 0m0.189s
фильтр.ш:
is_even () { (( $1 % 2 == 0 )) ;}
bash_filter() {
local cb=$1 i j a; local -n src=$2 dst=$3
for a in "${src[@]}"; do
"$cb" "$a" && dst[i++]=$a
done
for((j=${#dst[@]}; j>=i; j--)); do
unset dst[j]
done
}
grep_filter() {
local flt=$1; local -n src=$2 dst=$3
dst=($(printf '%d\n' "${src[@]}" | grep "$flt"))
}
timeit(){
echo "=== $1 ==="
time "$@" inlist outlist
[ "${#outlist[@]}" -lt 20 ] && echo "${outlist[@]}"
}
inlist=($(seq "${1-100000}"))
timeit bash_filter is_even
timeit grep_filter '[02468]$'