The advantage of shift in shell script over reassign value straightforward
shift
will remove the first positional argument, and shift every other argument left one.
For example, let's consider the following:
#!/bin/bash
echo "$@"
shift
echo "$@"
shift
echo "$@"
Given that echo "$@"
will print all of the arguments, if you were to run this, then the following would happen:
./test.bash 1 2 3 4 5
echo "$@" # prints 1 2 3 4 5
shift # Removes 1 and shifts everything else along
echo "$@" # prints 2 3 4 5
shift # shifting again
echo "$@" # prints 3 4 5
In your example, the script is parsing all of the flags. -i
and -h
are just switches and handle no following arguments. However, -f
requires a filename
.
The second shift
will process the flag, shift the arguments, and then process them again. Therefore you can have ./program.bash -i -f filename
. The -i
will be shifted by the second shift, and then the filename will be processed on the next loop.
If you were to run ./program.bash -f filename -i
, then the filename
would need to be shifted along with the -f
. Therefore, on the case block for -f
there is an extra shift. In this example, -f
would be shifted inside the case block, and then filename
would be shifted by the second shift
. Then the loop would run again to process any further flags.
As the while loop is [[ -n $1 ]]
, the loop will run until there are no more arguments.
Handling named arguments in bash
you mean something like this:
#!/bin/bash
deploy=false
uglify=false
while (( $# >= 1 )); do
case $1 in
--deploy) deploy=true;;
--uglify) uglify=true;;
*) break;
esac;
shift
done
echo "deploy: $deploy"
echo "uglify: $uglify"
examples
$ ./scriptname
deploy: false
uglify: false
$ ./scriptname --deploy
deploy: true
uglify: false
$ ./scriptname --uglily
deploy: false
uglify: true
$ ./scriptname --depoly --uglily
deploy: true
uglify: true
How to get arguments with flags in Bash
This is the idiom I usually use:
while test $# -gt 0; do
case "$1" in
-h|--help)
echo "$package - attempt to capture frames"
echo " "
echo "$package [options] application [arguments]"
echo " "
echo "options:"
echo "-h, --help show brief help"
echo "-a, --action=ACTION specify an action to use"
echo "-o, --output-dir=DIR specify a directory to store output in"
exit 0
;;
-a)
shift
if test $# -gt 0; then
export PROCESS=$1
else
echo "no process specified"
exit 1
fi
shift
;;
--action*)
export PROCESS=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
-o)
shift
if test $# -gt 0; then
export OUTPUT=$1
else
echo "no output dir specified"
exit 1
fi
shift
;;
--output-dir*)
export OUTPUT=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
*)
break
;;
esac
done
Key points are:
$#
is the number of arguments- while loop looks at all the arguments supplied, matching on their values inside a case statement
- shift takes the first one away. You can shift multiple times inside of a case statement to take multiple values.
Capture the output of Perl's 'system()'
That's what backticks are for. From perldoc perlfaq8
:
Why can't I get the output of a command with
system()
?You're confusing the purpose of
system()
and backticks (``).system()
runs a command and returns exit status information (as a 16 bit value:
the low 7 bits are the signal the process died from, if any, and the
high 8 bits are the actual exit value). Backticks (``) run a command
and return what it sent to STDOUT.my $exit_status = system("mail-users");
my $output_string = `ls`;
See perldoc perlop
for more details.
Unable to copy/paste in MinGW shell
Right-click on the title bar of the command window and select 'Properties', then on the 'Options' tab tick the box for the 'QuickEdit mode', then click 'Ok'.
After that you can paste text from the clipboard using the right mouse-button, highlight text while holding down the left mouse-button and copy selected text using the ENTER key.
This procedure works on Windows 7/8, not Windows 10.
Converting HeapSort and ShellSort from C to Pascal
Transferring comments into an answer.
In the Shell sort, the C loop is:
for (i = shift; i < n; i += 1){
and the Pascal loop is
For i:=shift to n Do
The Pascal loop is looping once too often; it needs to be:
For i := shift to n-1 Do
assuming expressions are allowed in loop limits — if not, you need an extra variable, roughly like this:
var ub: integer;
ub := n - 1;
For i := shift to ub Do
The C for loop is much more general and flexible than the Pascal for loop.
In the Heap sort, the C loop is:
do { … } while (N > 1);
and you've translated that to
repeat … until n > 1;
The terminating condition is wrong; until
is equivalent to while not
, so you need:
repeat … until n <= 1;
I've by no means scrutinized the whole of the Pascal code — and I have no Pascal compiler to test with — so there could be other issues to be resolved still, but these two should get you going. (Make sure you've checked all the occurrences of for
and repeat … until
for the problems outlined here.)
Related Topics
How to Use Netcat for Windows to Send a Binary File to a Tcp Connection
Size() VS Ls -La VS Du -H Which One Is Correct Size
Linux Kernel Device Driver to Dma from a Device into User-Space Memory
Which Real-Time Priority Is the Highest Priority in Linux
How to Confirm Sftp File Delivery
Split Files Using Tar, Gz, Zip, or Bzip2
Replace All Lines That Do Not Contain Matched String
How to Rename Multiple Files Beginning with a Unix Timestamp - Imapsync Issue
Oracle:Io Exception: the Network Adapter Could Not Establish the Connection
Using Gnu/Linux System Call 'Splice' for Zero-Copy Socket to Socket Data Transfers in Haskell
How to *Only* Get the Number of Bytes Available on a Disk in Bash
How to Append the Output to a File
How to Check for Opencv on Ubuntu 9.10
Removing Sensitive Data from Git. "Fatal: Ambiguous Argument 'Rm'"