Shell Scripting





The term 'shell' refers to a general class of text-based command interpreters most often associated with the UNIX and Linux operating systems. Popular shells include Bourne, Debian Almquist (dash), Korn (ksh), Bourne Again (bash) and the C shell family (csh). Some view the DOS 'cmd' prompt as a minimal shell of sorts. It is also possible to install Cygwin on Windows and emulate a full Unix environment with complete shell capabilities. Terminal emulators, such as xterm, GNOME Terminal and OS X Terminal, can be used to access shell.

Share tech news, updates, or what's on your mind.

Sign up to Post

Hi Bash/Shell experts.

Kindly pls help

I have a variable which get value like below. In some scenario I get only one mac address, in other scenario I get two. But I want only one :)

06:d1:eb:cf:5f:3c/ 06:f2:21:8a:9c:0a/

My request, How can I get only one even if I get two or more. I tried below, but I think, it will break if I get only one
MAC_ADDRESS=$(echo $MAC_ADDRESS | cut -d / -f 1)

could you help me the best approach please

thanks in advance
JavaScript Best Practices
LVL 13
JavaScript Best Practices

Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

I have two accounts with the same hosting provider.  They allow SSH access.  I created backup copies of websites on one account that I need to move to the other account.

I can move them individually, explicitly with "wget" but if I try to just pull all files from that one directory it fails.

Here is the command I am using, there are NO other sub-directories, just a bunch of files in one directory that I want to copy over from Account A to Account B.

wget -nc --level=1 --recursive --no-parent --accept jpa <url>/backups/

All I get when I run that command in the SSH portal is an "index.html" file and nothing more.  No error, just that one file (which is then automatically removed because it is not on my accept list).

I see other people (in general) are having a similar issue on StackOverflow (for example).

Server restriction maybe?  Problem with the command?

Thanks. :)
I'm consistently failing on the following:
- I have a bash script, say, a simplified content of which is listed below
- it is called with 0 or 1 argument, the normal value of which is "nomail" when I don't want a mail to be sent in the process
- the script first checks if nomail was provided as an argument and if yes gives the same value to the internal variable NOMAIL (otherwise empty). In the version below, it exports the value, as one of my (failed) attemps to solve the issue
- then runs the script somescript as user postgres (thru su)
- then launches another script mainscript with as argument the content of the NOMAIL variable

What happens:
- when running the example script from command line, everything works as expected, and the call to mainscript does indeed include the non-empty content of NOMAIL as as an argument
- but when running from cron, the call to mainscript is done with an empty value for NOMAIL!!!

(my first attempts were made without export, so I tried that just in despair!)



if  [ x$1 == 'xnomail' ] || [ x$2 == 'xnomail' ] ; then
      export NOMAIL='nomail'

su postgres -c "$LE_SCRIPT"

exec /root/ $NOMAIL

Open in new window

I have 2 scripts one is the Master_UpgradeScript.sql and the other is the scriptFileToRun.sql that I need to run to alter several schemas and add indexes and constraints to them. I feel like I am missing this: DEFINE schema_name=&1; from the scriptFileToRun.sql file and I don't know who this ties into the Master_UpgradeScript.sql.....

Could someone please verify if I need this (DEFINE schema_name=&1;) or not and if so please explain what it is doing and where it comes from? And how does it get into the ALTER script that needs to run?
Hi tesseract OCR experts,

I’ve just installed tesseract on my Raspberry Pi running Linux (Raspbain) and I’m trying to extract text from PNG screen shots taken on my phone.  (I have hundreds of these screen shots, all in the same size & format, taken over the last year using the LeafSpy Lite app, for the Nissan LEAF EV, and I'll be extracting text from all of them.)

The problem I have is, some of the text is not being extracted.

When I run this command:
$ tesseract sample1.png sample1
It produces sample1.txt (attached), which includes plenty of useful figures, but it excludes:
-      “11.84V” near the bottom left (nice to have this voltage figure, but not vital), and
-      “32.0%” at the bottom (I really need this SOC figure).

I tried feeding tesseract a negative (created with IrfanView on Windows) of the image, in case it was a black/white issue, but that gave the same output.
I tried cropping the 11.84V and 32.0% figures out to TIF files (see sample1_voltage.tif & sample1_soc.tif attached, also created with IrfanView on Windows) then running them through tesseract, and that:
-      failed for the 11.84V (see empty sample1_voltage.txt attached), but
-      worked for the 32.0% (see sample1_soc.txt attached).

I know bash and Perl scripting.  I don’t know Python, but Python is installed so it could be used if necessary, if someone else writes the code, but it's not my preference.
ImageMagicK is also installed, in case I need to use it for cropping or whatever.…
Within an ssh session on an instance, here is what I'd like to accomplish:

Steps in Script:
1.  Move a file (each file starts with "cfrtl4" - about 8 files total) from the remote systems /tmp directory to the etc/deployment-apps  
      directory as the SudoUser.
2.   Continue the same process until each "cfrtl4" file from the /tmp directory has been moved into the etc/deployment-apps
3.   Next, I'd like to chown the /opt/splunk/etc/deployment-apps directory as SudoUser:
       e.g. sudo chown -R splunk:splunk /opt/splunk/etc/deployment-apps
4.   I need to log out of SudoUser and log back in as splunkuser so that I can reboot the instance:
      sudo su splunk
5.   Now as the splunk user, I need to navigate to:  cd /opt/splunk/bin
6.   Once in the /bin directory, I need to issue a reboot command, e.g. ./splunk restart

#--- Execute the script from the /tmp directory ---
sudo mv cfrtl4_all_deployment_client/ /opt/splunk/etc/deployment-apps
sudo mv cfrtl4_all_indexer_base/ /opt/splunk/etc/deployment-apps
sudo mv " "
sudo mv " "
sudo mv " "

# --- Once all of the file shave been moved from /tmp to the /deployment-apps directory, then chown the deployment-apps    
     directory ---

sudo chown -R splunk:splunk /opt/splunk/etc/deployment-apps
# --- Exit out of sudouser ---
# --- Navigate to the bin directory ---
cd /opt/splunk/bin/
# ---Issue reboot command ---
./splunk restart
I've got a script located at:

I'm trying to invoke the script using:  

When the script runs it gives me this message:
Desktop/cfrtl4_all_indexer_base: No such file or directory

A portion of my script is below:
# ----- Variables -----
# ----- Script -----

# --- Search Head ---
sudo scp -r Desktop/Distributed_Lab/Apps/cfrtl4_all_indexer_base username@$SHIP:/tmp

Open in new window

I'm initiating the script from my local system where I have administrative rights.  However, I've tried the scp command with sudo and without.  Same result.  It keeps giving me this message:

"Desktop/cfrtl4_all_indexer_base: No such file or directory"

Why is the message referring to only the Desktop/ as the path and not the entire path?  More importantly, it's not seeing the file that I need to move from my Apps directory.  I created this script to move about 10 files over from my Desktop/Distributed_Lab/Apps directory which is on my local drive, on to a remote systems /tmp directory.   Any help is greatly appreciated!
How do i do a FULL directory search on a Linux box.  I want to look at the ENTIRE directory structure for a file.  In this example, I am looking for a file by the name of "email_log".

I am currently using:

find / -type f -name "email_log" and I've used sudo find / -type f -name "email_log" too, but when i hit enter, it wants the sudo password, which I enter in and it doesn't find anything. Is my search syntax incorrect?
I have a text file with 4 columns where the columns are delimited by a pipe character. The 3rd column, which is between the 2nd and 3rd pipe characters, may or may not have an extra pipe character.  I would like to replace these extra pipe characters in the 3rd column with a space.

File example:


In the 2nd line, in the 3rd column there is an extra pipe character. I would like to replace it with a space so that all lines have the same number of pipe characters. Any ideas as to how I could do it?
I am trying to create a Robocopy script that will copy files from one location to another location and purge the source files based on the timestamp. The script runs every hour at :00 and it copies the files to another location but, I want it to only delete the source files that are older than 15 minutes prior to the top of the hour. For example, the script runs at 11pm and I want it to only delete files older than 10:45pm. This is what I have currently in my script but, I don't know what switch(es) to use to do the file delete based on timestamp.

robocopy "\\\Share\CX" "D:\FC_Import\CXM" /S /E /SEC /MOV /COPYALL /V /NP /LOG+:"d:\Robocopy.txt" /R:3 /W:5
Introduction to R
LVL 13
Introduction to R

R is considered the predominant language for data scientist and statisticians. Learn how to use R for your own data science projects.

Hi Shell/Bash experts,

Would like to make an entry to a file in linux but only if it doesn't exists in the file please

Below is the sample entry that I would like to make in a text file /tmp/dbentry.txt

Thanks in advance
$VAR = “”

Need to extract 76.0. (1st 2 decimals)

I am using ${VAR:0:4} which returns 76.0

but if if $VAR has
3 digits (The first number can be 3 digits)

using ${VAR:0:4} does not work.
I have a bash script that returns the value.

For example,

bash $HOME/repos/newton/chromeDriverUpgrade.bash

I get 75.0.0

I assigned to a variable

CHROME=bash $HOME/repos/newton/chromeDriverUpgrade.bash

echo $CHROME

It does not print anything.

Can you help if anything is wrong.
Need to include (^) in the bash script variable.

I use the below to get the google chrome version

CHROMEDRIVER_VERSION=$(cat package.json \
  | grep chromedriver \
  | head -1 \
  | awk -F: '{ print $2 }' \
  | sed 's/[",]//g' \
  | tr -d '[[:space:]]')


prints out ^75.0.0

I use the below sed command to update package.json. The sed command updates the chromedriver if the value is 75..0.0 from the JSON file but if the chromedriver value is ^75.0.0, it does not update.

sed -i '' -e "/\"chromedriver\": /s/$CHROMEDRIVER_VERSION/$VER2/" package.json;

Please help
Hello all,
I have a directory on my macOS that every single name has a .dns at the end if it. for example:

Is there a sek, awk, perl or something I can run to remove the .dns file extension and leave it at
I dont care about preserving it, just change it all

They are located in this type dir structure

Thank you,
How can i write a shell script on RHEL 7.4 that does that counts number of line in netstat and if total lines exceeds 200 lines
send an email alert to "" with the number of lines and actual listing.


I want to schedule this script to run every 5 minutes via cron to monitor a connections performance issue.

Bash script inside package.json does not run when i use the command npm install.

I am in my local directory. I have package.json with the scripts section below

"scripts": {
    "preinstall": "echo preinstall",
    "UpgradeChrome": "bash chromeDriverUpgrade.bash"

when i run npm install, it runs preinstall command but not the bash script .

Do you see anything wrong with the above scripts section?
Is there a way to test a bash script in a way that it doesn't actually make any changes but it will show you the changes it would have made (or display the commands it would have executed)?
These are the Linux versions I'm using.
SUSE Linux Enterprise Server 11 SP4
Oracle Linux Server 7.6
From linux (SUSE Linux Enterprise Server 11 SP4) I want to read url's from a site. The URL's are embedded as shortcuts on the web page.
The site name
Then I want to pass this URL as a variable into a bash script

Here is a sample of a URL I'm trying to get.
Note there are severs URL's with different server names, ports, and the last part (AppsLogin) can also be different.
Become a Certified Penetration Testing Engineer
LVL 13
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

VERSION="Google Chrome 76.0.3809.100" . (Need to split and get only the version (76.0.3809.100)
#echo $VERSION

IFS=' ' read -a VERSION <<< "$VERSION"
    if "${VERSION[@]}"= "76.0.3809.100"
        echo "${VERSION[@]}"

It is not working. Please help.
How can I get an expect script to read a password from a file so it can be used to pass it to a program that requires that password.
I currently used autoexpect to create expect scripts, but the passwords are then hard coded.
Note: My OS is Linux

here is a snippet from my expect script
send -s -- "cd \$ADMIN_SCRIPTS_HOME"
expect -exact "cd \$ADMIN_SCRIPTS_HOME"
sleep .1
send -s -- "\r"
expect -exact "applmgr@appsrvr:/u01/blah/SID/R122/fs1/inst/apps/SID_hostname/admin/scripts> "
sleep .1
send -s -- "adop phase=fs_clone"
expect -exact "adop phase=fs_clone"
sleep .1
send -s -- "\r"
expect -exact "Enter the APPS password:"
sleep .1
send -s -- "hard_coded_password\r"

I want to be able to read the APPS password from a file and use it in this expect script.
Hi everyone,

I am trying to zip in zfiles<state>.zip file multiple (1000s) files (ASCII files) and get a count of each zip file in most efficient way (without dirrectory names and compress better) in Unix Bash script ( just like it was in the DCL language below.  If anyone knows how to do the same zipping process in the Unix bash script please let me know. Any suggestions or examples would be appriciated!

Note:  statelist.txt file has all states to loop through

Here is the DCL code portion that I am trying to convert to Unix bash scripting:
define/nolog DATA dir1/data
define/nolog proglog DATA:ZIP.LOG

laststate := ' '

 open/read statelist STATELIST.TXT
 read/end = endread statelist laststate

if f$search("ASCIIFILE%''laststate'%%%%%.TXT").EQS " " THEN -

! Create ZFILES<state>.zip  by zipping all ASCIIFILE files and send ZIP.LOG to the mail list
ZIP  -9V ZFILES'laststate'.ZIP - 

if .not. $status
  open/append pglog proglog
    write  pglog "--- Error Zipping ASCIIFILE*.TXT files ---"
   close pglog 
       SAY " --- Error Zipping ASCIIFILE*.TXT files ---"
 mail/subject="--- Zipping all files ==> Failure ---"

Open in new window

I have a bash script that calls more bash scripts, and those call other bash scripts, and some scripts run while others are running.
Each script writes some information into the same log file (script name, host it is running on, start time, stop time)
For example, this is what I want in the log file

RUNNING /DIR1/DIR2/DIR3/for_database/POST_DB_REFRESH/ on lddscoradb01 Start Date & Time: Fri Aug  2 09:28:51 CDT 2019
RUNNING /DIR1/DIR2/DIR3/for_database/POST_DB_REFRESH/ on lddscoradb01 Start Date & Time: Fri Aug  2 09:29:03 CDT 2019

Sometimes I get this in the log file, which I don’t want.
RUNNING /DIR1/DIR2/DIR3/RSYNC/ on hostname.apps.devRUNNING /DIR1/DIR2/DIR3/RSYNC/ on Start Date & Time:  Start Date & Time: Fri Aug  2 09:36:07 CDT 2019

I have scripts that run simultaneously, and I believe this is the crux of the problem. Multiple scripts can be writing at the same time.
Is there a way to lock the log file temporarily so that only that script can write to the log file, while at the same time it doesn’t cause a problem for the other scripts?

# This is the code at the top of the scripts
FILENAME=`basename $0`
echo ""
echo -n "RUNNING ${DIRECTORY}/${FILENAME} on ${SHORT_HOSTNAME}" | tee -a /DIR1/DIR2/DIR3/SCRIPT_CONTROL_LOG/master_script_control.log
echo " Start Date & Time: " | tee -a  …
Hi everyone,
I am trying to create a Menu script in Unix bash. A few issues that I am experiencing are:
1. Each Menu selection (#1,#2, and #3) ends right after I run each selection and the menu exits out back to the command line. I would like the Menu to ask a user if a user would like to continue with other selections (for example #2 or #3 if #1 was run in the first place) or exit the menu. Right now the Menu just exits after each selection without asking anything.  

2. In part of the selection #1, I would like to capture a value entered for "filecnt" (can be any number but 0) in the $parfl (parameter file). Right now this script allows to enter the value but that this value for some reason is not captured in the $parfl parameter file. The script creates the $parfl file but it is empty.  

What am I missing? Any suggestions or examples would be greatly appreciated. Thank you!

Open in new window

export DATA=/home/data
export EXEC=/home/exec

export parfl=${DATA}/parameterfile.txt
chmod 777 $parfl

# Menu

echo "             Control Menu"
echo " "
echo "Selection 1: Run Script1"
echo "Selection 2: Run Script2"
echo "Selection 3: Run Script3 "
echo "Selection 9: Exit System"
echo -e "\n"
echo -e "*** Make a selection from the Menu above and press enter ***"
read select

select=$(echo $select | tr '[:lower:]' '[:upper:]')
if [[ (("$select" <…
Trying to build sed command with variables and run the command (in a bash script on linux).
Ideally id like to substitute the string in the file. But I will settle for deleting it and replacing it.

LINE_TO_CHANGE=`grep -Hn ${CONTEXT_VARIABLE} ${FILE_TO_CHANGE} | awk -F'[:]' '{print $2}'`

grep -Hn ${CONTEXT_VARIABLE} ${FILE_TO_CHANGE} | awk -F'[:]' '{print $2}' returns 205

One of these two lines could exist in the file (between the double quotes on the next two lines)
"         <sslterminator oa_var="s_enable_sslterminator" customized="yes"/>"
"         <sslterminator oa_var="s_enable_sslterminator">customized</sslterminator>"

I want to change the entire line to (between the double quotes on the next line)
"         <sslterminator oa_var="s_enable_sslterminator">#</sslterminator}>"

Shell Scripting





The term 'shell' refers to a general class of text-based command interpreters most often associated with the UNIX and Linux operating systems. Popular shells include Bourne, Debian Almquist (dash), Korn (ksh), Bourne Again (bash) and the C shell family (csh). Some view the DOS 'cmd' prompt as a minimal shell of sorts. It is also possible to install Cygwin on Windows and emulate a full Unix environment with complete shell capabilities. Terminal emulators, such as xterm, GNOME Terminal and OS X Terminal, can be used to access shell.