.zshrc unrecognized condition on $- - zsh

I'm attempting to port over some functionality from my old .bashrc into my .zshrc and I'm having trouble with a condition that worked in bash.
Whenever I remote log in to my computer, I had bash check the $- variable to see if it was interactive. If it was, I would start up an emacs server if one wasn't already running and change to my code directory. Otherwise (if I was getting a file with scp, for example), I wouldn't do anything.
Here's the bit of code:
if [[ $- -regex-match "i" ]]; then
ps -u myusername | grep emacs > /dev/null
if [ $? -eq 0 ]; then
echo "emacs server already running"
else
emacsserver
fi
aliastocdtomydirectory
fi
And here's the error zsh gives me: .zshrc:125: unrecognized condition:$-'`
Does anyone know how to get around this error when using $- ? I've tried quoting it, wrapping it in $(echo $-) but none have worked. Thanks in advance.
Edit: If I switch my code to:
if [[ $- =~ "i" ]]; then
ps -u myusername | grep emacs > /dev/null
if [ $? -eq 0 ]; then
echo "emacs server already running"
else
emacsserver
fi
aliastocdtomydirectory
fi
I now get: .zshrc:125: condition expected: =~ I'm not sure exactly what zsh is interpreting incorrectly here as I'm not very familiar with the semantics of zsh's shell scripts. Could someone point me in the right direction on how to express this condition in zsh?

In zsh, you don't need to bother with $-, which is--I think--intended primarily for POSIX compatibility.
if [[ -o INTERACTIVE ]]; then
if ps -u myusername | grep -q emacs; then
echo "emacs server already running"
else
emacsserver
fi
aliastocdtomydirectory
fi

-regex-match is only available if tho module zsh/regex (man 1 zshmodules) is loaded. (The error message depends on the version: I get zsh: unknown condition: -regex-match if it is not loaded on 4.3.17, but zsh:1: unknown condition: -$- on 4.3.10).
You can try [[ $- =~ "i" ]] which is not dependend on additional modules.

Related

compadd failure during optparse-applicative zsh completion script

So I'm not exactly sure whether this is something wrong with optparse-applicative's script or if I'm using it wrong.
In the optparse-applicative readme, it states that programs are made available with automatic completion scripts, with options for zsh. For my program setup:
$> setup --zsh-completion-script `which setup`
Outputs:
#compdef setup
local request
local completions
local word
local index=$((CURRENT - 1))
request=(--bash-completion-enriched --bash-completion-index $index)
for arg in ${words[#]}; do
request=(${request[#]} --bash-completion-word $arg)
done
IFS=$'\n' completions=($( /Users/anrothan/.local/bin/setup "${request[#]}" ))
for word in $completions; do
local -a parts
# Split the line at a tab if there is one.
IFS=$'\t' parts=($( echo $word ))
if [[ -n $parts[2] ]]; then
if [[ $word[1] == "-" ]]; then
local desc=("$parts[1] ($parts[2])")
compadd -d desc -- $parts[1]
else
local desc=($(print -f "%-019s -- %s" $parts[1] $parts[2]))
compadd -l -d desc -- $parts[1]
fi
else
compadd -f -- $word
fi
done
I'm running the following in my zshrc (I use oh-my-zsh, but I removed it and this still happens in a bare-minimum config with only a small PATH addition to get the setup script).
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source <(setup --zsh-completion-script `which setup`)
I get the following error several times:
/dev/fd/11:compadd:24: can only be called from completion function
I've run compinit, and the completion script seems to look right to me, and I've looked around but I can't seem to figure out why this error is happening...
You don't need to source zsh-completion scripts, they just need to be added to your fpath parameter.
So just place the output of setup --zsh-completion-script $(which setup) in a file call _setup in $HOME/.config/zsh/completions.
fpath=($HOME/.config/zsh/completions $fpath)
autoload -U compinit && compinit

Shell script to open a link in currently running browser with urxvt click

I have a simple shell script:
#!/bin/zsh
URL=$1
function findBrowser {
processName=$1
ps ax | grep "$processName" | grep -v grep | wc -l
}
CNTFF=`findBrowser "firefox"`
CNTCH=`findBrowser "chromium"`
echo "$*" > $HOME/logurls
if [ $CNTFF -ge 1 ]
then
/usr/bin/firefox "$URL"
elif [ $CNTCH -ge 1 ]
then
/usr/bin/chromium "$URL"
else
echo "No running browser instance"
fi
if it's called from command line with a URL as an argument, everything works well. But if I specify the script in the configuration of urxvt, then no URL is passed (I'm checking logurls for that).
The configuration for urxvt is
URxvt.perl-ext-common: default,matcher,clipboard
URxvt.matcher.button: 1
URxvt.urlLauncher: $HOME/bin/openurl
the weirdest thing is that if I change urlLauncher to /usr/bin/firefox - then it opens the URL somehow. So looks like the URL is passed to firefox but not passed to my script.
What is the way to debug that? Or am I missing something about urxv?
update it works well if I specify /home/user/bin/openurl instead of $HOME/bin/openurl

How to determine if a specific module is loaded in linux kernel

I am just curious is there any way to determine if a particular module is loaded/installed.
$ lsmod lists all modules (device driver loaded).
Is there any way to check or a command that returns true/false boolean output if a module name is polled. For eg. if keyboard.o exists return true else false. I need this tip to complete my driver auto refresh program.
PS: tried modinfo. I am using busybox client in my test DUT so can you give some alternatives other than modinfo?
The modinfo module method does not work well for me. I prefer this method that is similar to the alternative method proposed:
#!/bin/sh
MODULE="$1"
if lsmod | grep -wq "$MODULE"; then
echo "$MODULE is loaded!"
exit 0
else
echo "$MODULE is not loaded!"
exit 1
fi
not sure if modinfo modname and checking $? will work for you, just a suggestion.
/tmp$ sudo modinfo e1000
/tmp$ echo $?
0
/tmp$ sudo modinfo keyboard
ERROR: modinfo: could not find module keyboard
/tmp$ echo $?
1
alternatively you also grep /proc/modules
The --first-time flag causes modprobe to fail if the module is already loaded. That in conjunction with the --dry-run (or the shorthand -n) flag makes a nice test:
modprobe -n --first-time $MODULE && echo "Not loaded" || echo "Loaded"
Edit 1: As #Nobody pointed out this also prints Loaded if the module does not exist. We can fix this by combining it with modinfo:
modinfo $MODULE >/dev/null 2>/dev/null &&
! modprobe -n --first-time $MODULE 2>/dev/null &&
echo "Loaded" || echo "Not loaded"
Edit 2: On some systems modprobe lives in /usr/sbin, which is not in the $PATH unless you are root. In that case you have to substitute modprobe for /usr/sbin/modprobe in the above.
I wrote this:
MODULE=snd_aloop # for example
test -n "$(grep -e "^$MODULE " /proc/modules)" && echo "Loaded" || echo "Not loaded"
It checks in /proc/modules. If the module is mentioned there, it's assumed to be loaded, otherwise not.
The others seemed too long to me (the other short one requires root, this does not). Of course it's just written out what was already mentioned as "alternatives".
Caution: modprobe accepts some variants of module names other than the primary listed in /proc/modules. For example loading snd-aloop works, but the module is named snd_aloop and is listed as such in /proc/modules and when using rmmod that's also the only name that will work.
My short way to find if a given module is actually loaded:
cat /proc/modules | grep -c nfnetlink
which outputs
2
That 2 (TWO) means the module is LOADED. The actual output without -c shows all loaded modules with MODULENAME - -c counts the lines that contain MODULENAME. So if you have 0 (ZERO) lines as output then the module is not loaded
The better idea is to create a bash function:
#!/bin/sh
function moduleExist(){
MODULE="$1"
if lsmod | grep "$MODULE" &> /dev/null ; then
return 0
else
return 1
fi
}
if moduleExist "module name"; then
#do somthing
fi
!/bin/sh
# Module
MODULE="scsi_dh_rdac"
#Variables check if module loaded or not
MODEXIST=/sbin/lsmod | grep "$MODULE"
if [ -z "$MODEXIST" ]; then
/sbin/modprobe "$MODULE" >/dev/null 2>&1
fi
module list
Returns:
Currently Loaded Modulefiles:
1) /coverm/0.3.0 2) /parallel/20180222
grep -wEq "^${module%.o}" /proc/modules
returns true (e.g. can be used in an if) whether you ask for keyboard or keyboard.o
grep -q $pattern against lsmod or /proc/modules, which are available on most systems and a standard "source of truth"
lsmod | grep -q $pattern
$ lsmod | grep -q msr
$ echo $?
0
$ lsmod | grep -q duediligencemuch
$ echo $?
1

how to translate the hostname solaris?

can any one translate or explain the following unix script for me please, when i actually run the script in the solaris server, it gives me the server name, but not really sure how this script work, can any one explain it in simple baby language ? Thanks
TEXTDOMAIN=SUNW_OST_OSCMD export TEXTDOMAIN
if [ $# -eq 0 ]; then
/bin/uname -n
elif [ $# -eq 1 ]; then
/bin/uname -S $1
else
echo `/bin/gettext "Usage: hostname [name]"`
exit 1
fi
$# reads command line arguments
if there are none call uname -n
if there is one call uname -S $1 (which is the command line argument.)
See man uname to discover the differences in these calls.
If the script is executed with 0 arguments
it will just run uname manpage printing you system name
if script is executed with 1 argument
it will change your system name ( you have to be superuser)
else prints usage

shell script help - checking for file exists

I'm not sure why this code isn't working. Its not going to the copy command.
I successfully run this manually on the command line (without the check)
I don't think i'm performing a correct file check? Is there a better, cleaner way to write this?
I just want to make sure the file exists, if so, copy it over. Thanks.
#!/bin/bash
if [ $# != 1 ]; then
echo "Usage: getcnf.sh <remote-host>" 2>&1
exit 1
fi
#Declare variables
HOURDATE=`date '+%Y%m%d%H%M'`
STAMP=`date '+%Y%m%d-%H:%M'`
REMOTE_MYCNF=/var/log/mysoft/mysoft.log
BACKUP_DIR=/home/mysql/dev/logs/
export REMOTE_MYCNF HOURDATE STAMP
#Copy file over
echo "Checking for mysoft.log file $REMOTE_MYCNF $STAMP" 2>&1
if [ -f $REMOTE_MYCNF ]; then
echo "File exists lets bring a copy over...." 2>&1
/usr/bin/scp $1:$REMOTE_MYCNF $BACKUP_DIR$1.mysoft.log
echo "END CP" 2>&1
exit 0
else
echo "Unable to get file" 2>&1
exit 0
fi
your checking existing file on remote computer seems like:
you should do:
ssh $host "test -f $file"
if [ $? = 0 ]; then
use sh -x script.sh to see what is happening.
You are testing for the existence of a remote file
$1:$REMOTE_MYCNF
using the local name $REMOTE_MYCNF. The if test is never satisfied.
You don't check that $1 is set.
Your file check runs on the local machine - not on the remote.
Change your if to:
if[! -f $REMOTE_MYCNF -o ! -d $REMOTE_MYCNF];

Resources