# Scripting with spmenu This wiki article walks you through how to actually write a script using spmenu. ## Deciding what to write Before you write anything, you need to have a concept. For this example, we're going to write a script which lists out all Arch packages you could install and then installs it. You could of course do anything you want, though. ## spmenu basics The core concept of spmenu is to take standard input, list out items separated by a newline character, and output the selected item. For example `printf "1\n2\n3\n" | spmenu --lines 30 --prompt 'Select a number'` will allow you to choose between 1, 2 and 3. The selected item is then output to standard output (stdout) ## Starting off First, I like to start off my scripts with a `main` function. I would start like this: ``` #!/bin/sh # My super awesome shell script # Licensed under the GNU General Public License version 3.0 # See LICENSE file for more information. main() { : } ``` Now, I know the command to list out all packages in the Arch repositories on your system is `pacman -Sl`. This is going to list out the repository name followed by a space though, and we don't really need to see that. So what I'm going to do is `pacman -Sl | awk '{ print $2 }'`, which gets the second and final column. ``` [speedie@arch ~]$ pacman -Sl | awk '{ print $2 }' acl amd-ucode archlinux-keyring argon2 attr audit autoconf automake b43-fwctter base ... ``` Then what I would do is create another function, and perhaps call it `list_packages()` or something like that, and then I would replace the placeholder `:` with assigning a variable. ``` ... list_packages() { pacman -Sl | awk '{ print $2 }' } main() { sel_item="$(list_packages | spmenu --lines 10 --columns 3 --prompt "Select a package to install:" } ``` ## Checking the output Alright, now we have the selected item in a variable called `sel_item`. We can easily print what this variable contains by running something like `printf "%s\n" "$sel_item"`. Now we need to use this variable for something. What I would do next is use something like sudo or doas, and enable root without a password. This *could* be insecure, so be careful. For this example though, I'm going to assume you're using sudo, and sudo can execute `pacman -S` without a password. ``` ... main() { sel_item="$(list_packages | spmenu --lines 10 --columns 3 --prompt "Select a package to install:")" sudo pacman -S --noconfirm "${sel_item}" } ``` ## Notify Now what I like to do is add a nice litte notification if the package installed successfully. This is optional but I would do it like this: ``` ... main() { sel_item="$(list_packages | spmenu --lines 10 --columns 3 --prompt "Select a package to install:")" sudo pacman -S --noconfirm "${sel_item}" && notify-send "Installed" "Installed '${sel_item}'." || notify-send "Failed" "Installation of package '${sel_item}' failed." } ``` Now, finally we need to call the `main()` function, so simply add `main` to the bottom of the script. The script should look something like this: ``` #!/bin/sh # My super awesome shell script # Licensed under the GNU General Public License version 3.0 # See LICENSE file for more information. list_packages() { pacman -Sl | awk '{ print $2 }' } main() { sel_item="$(list_packages | spmenu --lines 10 --columns 3 --prompt "Select a package to install:")" [ -z "${sel_item}" ] && exit # This will exit if we didn't select anything. sudo pacman -S --noconfirm "${sel_item}" && notify-send "Installed" "Installed '${sel_item}'." || notify-send "Failed" "Installation of package '${sel_item}' failed." } main ``` Now, you could easily expand this to do removal as well, but I'm not going to cover that.