Pass a bash array as an argument

I have a bash script in which I’m using an array to get a list of files and I needed to pass the content of this array as an argument, to send an email to some users.

This is the array:

RAW_LIST="$(echo "ls -1 /download")"
declare -a LIST
readarray -t LIST <<<"${RAW_LIST}"

This is how I passed the array to bash:

printf %"s\n"  "${LIST[@]:1}" | /bin/mail -s "$SUBJECT" "$EMAIL"

Trailing :1 in the array will consider all the elements after element [0] as, in this specific case, it'd be ls -1, pretty useless sending it to the user.

Recover GRUB in CentOS 7

To recover GRUB, you’ll need the OS ISO image, in this case CentOS 7, and boot from it.

From the ISO menu, choose Trobleshooting -> Rescue a CentOS system and then 1) Continue; the system will be mounted under /mnt/sysimage.

To make your system the root environment run:

chroot /mnt/sysimage

Identify GRUB installation:

ls /sbin | grep grub

Install GRUB:

/sbin/grub2-install /dev/sdX

Exit and reboot.

Script: receive files via SFTP

In the past days I had to write a script to download files from a remote server using an SFTP connection; this script will be run by cron.

The goal was to download the files on my server and delete them on the remote machine after being downloaded.

I used an array to get the list of the current files on the remote server and a for-loop to download them.

#!/bin/bash
# 
# 20180801
#
# Receive files via SFTP


LOGFILE=/var/tmp/receivefiles.$(date -I).log
echo "START: $(date)" >>$LOGFILE

# Connection data
HOST='XXX.XXX.XXX.XXX'
PORT='22'
USER='mashiny'

# Where to download files
cd /home/mashiny/download

# File list
LIST_RAW="$(echo "ls -1 /out" | sftp -oPort=$PORT $USER@$HOST 2>/dev/null)"
declare -a LIST
readarray -t LIST <<<"${LIST_RAW}"

if   [[ "${#LIST[@]}" -lt 1 ]]; then
    echo "Unknown error in SFTP connection" >>$LOGFILE
    exit 1
elif [[  "${#LIST[@]}" -lt 2 ]]; then
    echo "No files to download" >>$LOGFILE
    exit 0
fi

# Connection via SFTP and download files
for FILE in "${LIST[@]:1}"
do
    # Download
    echo "get $FILE" | sftp -oPort=$PORT $USER@$HOST &>/dev/null
    [ $? -ne 0 ] && echo "$FILE download failed" >>$LOGFILE && continue
    echo "$FILE downloaded" >>$LOGFILE

    # Delete on remote dir
    echo "rm $FILE" | sftp -oPort=$PORT $USER@$HOST &>/dev/null
    [ $? -ne 0 ] && echo "$FILE not removed" >>$LOGFILE && continue
    echo "$FILE removed" >>$LOGFILE
done

echo "END:   $(date)" >>$LOGFILE
exit 0

Configure an IP address in Solaris 11

ipadm create-addr is used to assign an IP address to an interface. Its syntax:

ipadm create-addr -T address-type -a address/netmask addrobj

-T address-type refers to static, dhcp or addrconf (for automatically generated IPv6 addresses).

addrobj is an identifier for the unique IP used in the system.

dladm show-phys
LINK              MEDIA                STATE      SPEED  DUPLEX    DEVICE
net0              Ethernet             up         1000   full      e1000g0

Static IP

ipadm create-ip net0

ipadm create-addr -T static -a 10.0.2.15/24 net0/v4

ipadm show-addr
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
net0/v4           static   ok           10.0.2.15/24

Dynamic IP

ipadm create-ip net0

ipadm create-addr -T dhcp net0/v4

ipadm show-addr
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
net0/v4           dhcp     ok           10.8.29.188/24

CIFS: mount error(112): Host is down

When trying to mount a Windows share using mount, I ran into this problem:

mount -v -t cifs -o username=username,password=password //hostname/sharename /mnt
mount.cifs kernel mount options: ip=XXX.XXX.XXX.XXX,unc=\\hostname\sharename,user=username,prefixpath=sharename,pass=********
mount error(112): Host is down

In my case, the error was due to a protocol mismatch when trying to mount the share: in the latest versions of Windows Server, SMBv1 is disabled.

To reach this conclusion, I ran smbclient in debug mode:

smbclient -L //hostname/sharename -U username -d 3
protocol negotiation failed: NT_STATUS_CONNECTION_RESET

To overcome this issue, I specified the protocol when using mount:

mount -t cifs -o username=username,password=password,vers=3.0 //hostname/sharename /mnt

If you want to use smbclient, add the -m option:

smbclient -L //hostname/sharename -U username -m SMB3

Mounting a Windows share using CIFS

Windows shares can be mounted using cifs option:

mount -t cifs -o username=username,password=password //hostname/sharename /mnt

By default, Windows shares are mounted with 0777 permissions in Linux.

You can change the default permissions using dir_mode and file_mode options in mount:

mount -t cifs -o username=username,password=password,dir_mode=0755,file_mode=0755 //hostname/sharename /mnt

To make the mount persistent, add the entry to /etc/fstab:

//hostname/sharename    /mountpoint   cifs  _netdev,username=username,password=password,dir_mode=0755,file_mode=0755,uid=500,gid=500 0 0

LVM: creating a new LV from unallocated space

A logical volume provides storage virtualization so you are not restricted to physical disks sizes. The hardware storage configuration is hidden and the logical volume can be resized and moved on the fly.

An LVM Logical Volume has three components:

  1. Physical Volumes (PV)
  2. Volume Groups (VG)
  3. Logical Volumes (LV)

First of all, you have to initialize a new PV using the pvcreate command:

pvcreate /dev/sdc*

You can create a PV from a whole disk rather than partitions.

Continue reading