#! /usr/bin/bash
for var in "$#"
do
echo $var
done
simple shell script which displays each of the command
line arguments, one at a time and stops displaying command line
arguments when it gets an argument whose value is “stop”.?
IIUC, try this:
#!/bin/bash
for var in "$#"
do
if [[ "$var" == 'stop' ]]; then
exit 0
else
echo "$var"
fi
done
Process args with a while loop:
#!/usr/bin/env bash
while test -n "$1"; do
test "$1" != 'stop' && echo "$1" && shift || break
done
Related
This question already has answers here:
An example of how to use getopts in bash
(8 answers)
Closed 7 months ago.
Can some please help how to pass named command line arguments to my shell script. Something like below.
./myOwnShellScript.sh -name Thor -tool Hammer
Below is one way to implement
#!/bin/bash
#################################################################################################
# Script name - myOwnShellScript.sh
# Description - This script is used to implement my own logic.
# Author - Tony
#################################################################################################
function usage(){
echo "Here is usage..."
echo "./myOwnShellScript.sh -name <<Name of your hero>> -tool <<your hero's tool>>"
}
function paramMap(){
declare -A params=( ["name"]="name" ["tool"]="tool" )
paramVarName="${params[${1}]}"
[ -z "${paramVarName}" ] && echo "info" || echo "${paramVarName}"
}
####################################################################################
#----------------------------------------------------------------------------------#
# Main starts, the script execution starts here. #
#----------------------------------------------------------------------------------#
####################################################################################
export TERM="xterm"
clear
trap "exit 1" TERM
export TOP_PID=$$
CURR_TIME=$(date +"%Y-%m-%d-%T")
echo -e "\n**********************************************"
echo -e "\n myOwnShellScript.sh Script Started ${CURR_TIME}"
echo -e "\n**********************************************"
##################################################################################################
# Variable Declaration
##################################################################################################
#Read command line parameters and set script variables.
while [ $# -gt 0 ]; do
if [[ $1 == *"-"* ]]; then
v="${1/-/}"
p=$(paramMap ${v})
paramValue=$([ -z "$2" ] && echo "1" || echo "$2")
declare $p="${paramValue}"
fi
shift
done
echo "Here is your hero ${name}"
echo "His tool is ${tool}"
I want to check if some variable is starting with some string (A-) and ending with digit in shell script.
My script (test.sh):
#!/bin/bash
VAR=A-1
if [[ $VAR =~ A-*[0-9 ] ]]; then
echo "yes"
else
echo "no"
fi
The error I get after running sh test.sh:
test.sh: 5: test.sh: [[: not found
I tried to change the concession to:
if [ $VAR =~ A-*[0-9 ] ]; then
and got this error: test.sh: 5: [: A-1: unexpected operator
The variables should always be quoted:
VAR="A-1"
The issue in your code is with the space in the square brackets: [...] which you've defined in the regex: [0-9 ].
There shouldn't be any space within it.
The correct code to check if some variable is starting with A- and ending with digit should be :
#!/bin/bash
VAR="A-1"
if [[ "$VAR" =~ ^A-.*[0-9]$ ]]; then
echo "yes"
else
echo "no"
fi
Please note the double quotes around the variable VAR.
As per the OP's comments, it looks like sh is being used instead bash , as the regex matching operator : =~ doesn't work in sh and is bash specific.
Updated code using sh:
#!/bin/sh
VAR="A-1"
if echo "$VAR"| grep -Eq "^A-.*[0-9]$"
then
echo "Yes"
else
echo "no"
fi
The regex to match a string which starts with A- and ends with a digit
should be: ^A-.*[0-9]$ or more strictly ^A-.*[[:digit:]]$.
Then please modify your scpipt as:
#!/bin/bash
VAR="A-1"
if [[ $VAR =~ ^A-.*[0-9]$ ]]; then
echo "yes"
else
echo "no"
fi
Then invoke it with bash test.sh, not with sh test.sh.
sh test.sh does not use bash to run the script, it uses sh, which, depending on the system, may not have the same capabilities as bash.
You can use:
bash test.sh
Or:
chmod a+rx test.sh # one time only
./test.sh # your script is set to use /bin/bash in the #! line.
Try something like : ${VAR:${#VAR}-1:1}
Cf. https://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html
[[ "${VAR:${#VAR}-1:1}" =~ [0-9] ]] && echo yes
I am looking to create a shell script that reads command line arguments, then concatenates the contents of those files and print it to stdout. I need to verify the files passed to the command line exist.
I have written some code so far, but the script only works if only one command line argument is passed. If passing more than one argument, the error checking I have tried does not work.
#!/bin/bash
if [ $# -eq 0 ]; then
echo -e "Usage: concat FILE ... \nDescription: Concatenates FILE(s)
to standard output separating them with divider -----."
exit 1
fi
for var in "$#"
do
if [[ ! -e $# ]]; then
echo "One or more files does not exist"
exit 1
fi
done
for var in "$#"
do
if [ -f $var ]; then
cat $var
echo "-----"
exit 0
fi
done
I need to fix the error checking on this so that every command line argument is checked to be an existing file. If a file does not exist, the error must be printed to stderr and nothing should be printed to stdout.
You have a bug in line 11:
if [[ ! -e $# ]]; then
You do need to check for a given file here using $var like that:
if [[ ! -e "$var" ]]; then
And you exit prematurely in line 23 - you will always print only a
single file. And remember to always quote your variable because
otherwise your script would not run correctly on files that have a whitespaces in the name, for example:
$ echo a line > 'a b'
$ cat 'a b'
a line
$ ./concat.sh 'a b'
cat: a: No such file or directory
cat: b: No such file or directory
-----.
You said:
if a file does not exist, the error must be printed to stderr and
nothing should be printed to stdout.
You aren't printing anything to stderr at the moment, if you want to
you should do:
echo ... >&2
And you should use printf instead of echo as it's more portable
even though you're using Bash.
All in all, your script could look like this:
#!/bin/bash
if [ $# -eq 0 ]; then
printf "Usage: concat FILE ... \nDescription: Concatenates FILE(s) to standard output separating them with divider -----.\n" >&2
exit 1
fi
for var in "$#"
do
if [[ ! -e "$var" ]]; then
printf "One or more files does not exist\n" >&2
exit 1
fi
done
for var in "$#"
do
if [ -f "$var" ]; then
cat "$var"
printf -- "-----\n"
fi
done
exit 0
I want to get NetworkActivity_5851_*_09-04-2016.done string from NetworkActivity_5851_2326316_09-04-2016.log.gz and here the code I wrote
local file="$1"
local extension="${file##*.}"
if [ $extension = 'done' ]; then
local files=`basename $file`
files="${files#*_}"
files="${files#*_}"
files="${files%_*}"
local q=_"$files"_
local mask="${file/done/log.gz}"
mask="${mask/${q}/_*_}"
r=`ls "${mask}" | wc -l`
and it works correct, but when I run it with python script it fails. I mean r variable has wrong value.
Here is code in Python
shell = Shell(RUN_SCRIPT_2, LOGFILE)
where Shell is
class Shell():
"""
Base class for the shell script object which
is under testing.
"""
def __init__(self, path_to_script, path_to_log=None):
"""
executes shell script and store results
of STDOUT and STDERR into appropriate attributes
"""
self.path_to_log = path_to_log
# clear log file before run
if self.path_to_log:
open(self.path_to_log, 'w').close()
shell = subprocess.Popen([path_to_script],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
# the line below makes sure shell command execution finished
self.stdout, self.stderr = shell.communicate()
self.log_data = self.get_log_data()
and file path_to_script is
echo 'Start'
file="${SOURCE_DIR}/NetworkActivity_5851_3_09-04-2016.done"
extension="${file##*.}"
if [ $extension = 'done' ]; then
files=`basename $file`
files="${files#*_}"
files="${files#*_}"
files="${files%_*}"
q=_"$files"_
mask="${file/done/log.gz}"
mask="${mask/${q}/_*_}"
r=`ls "${mask}" | wc -l`
echo $r
if [ $r = $files ]; then
rez=0
else rez=1
fi
fi
if [[ $rez -eq 1 ]]; then
echo "Failure"
else echo "Success"
fi
echo 'Finish'
So when I run path_to_script from terminal r variable sets number of files when I run it using Python it sets 0.
You can do that using bash string-manipulation techniques alone.
$ inputString="NetworkActivity_5851_2326316_09-04-2016.log.gz"
$ substring="${inputString%%.*}" # Removing the part after the first '.'
$ [[ $substring =~ .*_([[:digit:]]+)_.* ]] && NUM=${BASH_REMATCH[1]} # Extracting the number you want to replace
$ finalString="${substring/$NUM/*}.done" # Forming the final string with the extension
$ printf "%s\n" "$finalString"
NetworkActivity_5851_*_09-04-2016.done
You can put together this logic in a shell script and run the same for multiple files you have. The above commands though can be run directly on the console.
Well, I'm based on your first paragraph. Hope I got the problem! This is my solution with Perl and regular expression with a simple command line.
~$ gunzip NetworkActivity_5851_2326316_09-04-2016.log.gz && perl -e 'while(<>){print $_ if $_ =~ /NetworkActivity_\d+_.*_\d{2}\-\d{2}-\d{4}\.done/}' NetworkActivity_5851_2326316_09-04-2016.log
Hope it helps!
Suppose I created my own bash script with a command called customcmd
I want it so that if I type in customcmd into the terminal, every subsequent commands following it will also execute customcmd
so suppose I do
>customcmd
>param1
>param2
>param3
I want this to be the equivalent of
>customcmd
>customcmd param1
>customcmd param2
>customcmd param3
ie. I want it to be so that by executing customcmd once, I won't have to type in customcmd again and I want to have the command line parse every single command I type afterwards to automatically be parameters to customcmd...
how do I go about achieving this when writing the bash script?
If I understand your question correctly, I'd do the following:
Create a script, eg mycommand.sh:
#!/bin/bash
while [[ 1 ]]; do
read _INPUT
echo $_INPUT
done
initialize an infinite loop
for each iteration, get the user input ( whatever it is ) and run it through the command you specify in the while loop ( if your script needs to parse multiple arguments, you can swap our echo with a function that can handle that )
Hope that helps!
This could be one of your forms.
#!/bin/bash
shopt -s extglob
function customcmd {
# Do something with "$#".
echo "$*"
}
while read -er INPUT -p ">" && [[ $INPUT != *([[:blank:]]) ]]; do
if [[ $INPUT == customcmd ]]; then
customcmd
while read -er INPUT -p ">" && [[ $INPUT != *([[:blank:]]) ]]; do
customcmd "$INPUT"
done
fi
done
Or this:
#!/bin/bash
shopt -s extglob
function customcmd {
if [[ $# -gt 0 ]]; then
# Do something with "$#".
echo "$*"
else
local INPUT
while read -er INPUT -p ">" && [[ $INPUT != *([[:blank:]]) ]]; do
customcmd "$INPUT"
done
fi
}
while read -era INPUT -p ">" && [[ $INPUT != *([[:blank:]]) ]]; do
case "$INPUT" in
customcmd)
customcmd "${INPUT[#]:2}"
;;
# ...
esac
done
** In arrays $INPUT is equivalent to ${INPUT[0]}, although other people would disagree using the former since it's less "documentive", but every tool has their own traditionally accepted hacks which same people would allow just like those hacks in Awk, and not any Wiki or he who thinks is a more veteran Bash user could dictate which should be standard.