[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bash uses tmp files for inter-process communication instead of pipes
From: |
Linda Walsh |
Subject: |
Re: bash uses tmp files for inter-process communication instead of pipes? |
Date: |
Tue, 07 Oct 2014 15:03:43 -0700 |
User-agent: |
Thunderbird |
Pierre Gaston wrote:
That's where you are wrong, there is no reason for *your* use case, but the
basic idea behind process substitution is to be able to use a pipe in a
place where you normally need a file name.
Well, that's not what I needed it for. I needed to read from a child
process that
changed directories.
----
How can you say there is no reason for my use case...
It's not thoroughly polished yet, but it does work. It can rename and
reorder your
network interfaces on boot so you can keep them with consistent names and
ordering -- something systemd doesn't seem to support. Furthermore, it
doesn't depend on any suse library code -- which they've been putting in
hooks and traps for those not using systemd. Supposedly people not using
systemd won't be able to boot their systems.
This is one of my side projects to keep my system booting and to make
available
to anyone who might want to use it. But you call that no reason?
Sigh.
IF you want to see what I was doing in context, its attached.
It's a stand alone script to tell you if your interfaces are in your
desired order, reorder them if you wish, and act as a startup/shutdown
script
to fix things each boot. I haven't spent any time in cleanup, but it's
still
not bad code. See if the code is not readable -- even for shell!
#!/bin/bash
#boot.assign_network_names
### BEGIN INIT INFO
# Provides: net-devices
# Required-Start: boot.udev boot.device-mapper boot.localfs
# Required-Stop: $null
# Default-Start: B
# Default-Stop:
# Short-Description: reorder and rename net devices
# Description: reorder and rename net devs if needed
### END INIT INFO
#
# assign network names as rc-script
# L A Walsh, (free to use/modify/distribute to nice people) (c) 2013-2014
#
#include standard template:
_prgpth=${0:?}; _prgpth=${_prgpth#-} _prg=${_prgpth##*/};
_prgdr=${_prgpth%/$_prg}
[[ -z $_prgdr || $_prg == $_prgdr ]] && _prgdr="$PWD"
#if ! typeset -f include >&/dev/null ;then
# source ${_LOCAL_DIR:=/etc/local}/bash_env.sh;
#fi
export PATH="/etc/local/bin:/etc/local/lib:$PATH"
export
PS4='>>${BASH_SOURCE:+${BASH_SOURCE[0]}}#${LINENO}${FUNCNAME:+(${FUNCNAME[0]})}>
'
#include stdalias (needed entries included "inline", below)
shopt -s extglob expand_aliases
alias dcl=declare sub=function
alias int=dcl\ -i map=dcl\ -A
hash=dcl\ -A array=dcl\ -a
alias lower=dcl\ -l upper=dcl\ -u
string=dcl my=dcl
alias map2int=dcl\ -Ai intArray=dcl\ -ia
cfg_fn="/etc/sysconfig/assign_netif_names"
[[ -f $cfg_fn ]] || {
echo "Cannot find required config file: $cfg_fn"; exit 1; }
# expected variables to be read in
array needed_drivers
array Linknames
array Default
map if2hw
. $cfg_fn || { echo "Error in reading config file $cfg_fn"; exit 2; }
DfltRE="^+(${Default_good[@]})$"
DfltRE=${DfltRE// /|}
declare -a down_ln=()
for ln in "${Linknames[@]}"; do
[[ $DfltRE =~ $ln ]] && continue;
down_ln+=($ln)
done
map hw2if
for intf in "${!if2hw[@]}" ; do
addr=${if2hw[$intf]}
hw2if[$addr]="$intf"
done
############# end read config ######
#include rc.status -- essential funcs included below:
int rc_status=0
sub rc_reset { rc_status=0; }
sub rc_status {
rc_status=$?;
if ((rc_status)) && { (($#)) && [[ $1 = -v ]] ; }; then
echo "Abnormal rc_status was $rc_status."
elif (($#)) && [[ $1 = -v ]] ; then
echo "rc_status: ok"
fi
}
sub rc_exit {
rc_status=$?;
rc_status
exit $rc_status
}
sub warn () { local msg="Warning: ${1:-"general"}"
printf "%s" >&2 "$msg"
}
sub die () { int stat=$?; local msg="Error. ${1:-"unknown"}"
echo "$msg (errno=$stat)" >&2
(exit $stat);
#sets $? (doesn't exit inside ()
rc_status -v
rc_exit
exit $stat
# exit unless die called in
subshell
}
sysfs=/sys
sysnet=$sysfs/class/net
[[ -d $sysfs && -d $sysnet ]] ||
sysnet=$sysfs/class/net
sys_modules=$sysfs/module
if [[ -z $(type -P modprobe) ]]; then # verify find of modprobe
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH
fi
if [[ -n $(type -P modprobe) ]]; then # if found, alias it
alias modprobe="$(type -P modprobe)"
else
# only throw
error if needed
alias modprobe="die 'cannot load required modules'"
fi
if [[ -z $(type -P ip ) ]]; then # ip is needed,
so no delayed error
die "Cannot find 'ip' util -- needed for network setup"
fi
alias ip="$(type -P ip)"
sub varflags() {
# util: get dcl flags of a var
my var="${1:-""}"
read out <<<$(declare -p "$var" )
[[ $out =~ /^declare.*=.*$/ ]] || die "no such variable"
out="${out%% +([^-])=*}"
out="${out#declare }"
[[ ${out:0:1} == - ]] || { echo ""; return 0 ; }
echo "${out#-}"
}
sub isarray() {
# util: chk if pass name is an array
my name="${1:-""}"
flags=$(varflags $name)
[[ $flags =~ a ]] && return 0
return 1
}
sub ipcmd () { # unused/incomplete
my ipcmd="${1:?}"; shift; array tmpbuff
my outbuff="${2:-tmpbuff}"
}
sub rev () { # reverse elements of a
list, 1/iteration (recursive)
(($#==0)) && { echo ""; return 0 ;}
my element=${1:?}; shift;
(($#==0)) && { echo "$element"; return 0;}
echo "$(rev "$@") $element"
}
sub rename_if () {
my old_name=${1:?} new_name=${2:?}
echo ip link set name "$new_name" dev "$old_name"
}
sub down_if () {
my if_name=${1:?}
echo ip link set down dev "$if_name"
}
sub set_links_down() {
# can't operate on up links
for int in "${down_ln[@]}"; do
down_if "$int" down
done
}
sub vrfy_drivers () {
int errors=0;
for i in ${needed_drivers[@]} ; do
if [[ ! -d $sys_modules/$i ]]; then # check for loaded or
static drivers
modprobe "$i" || {
warn "Module $i is not in kernel and can't be
loaded"
errors+=1
}
fi
done
return $errors
}
map act_hw2if
#actual values (to be read in)
map act_if2hw
map XIF
#tmp array to hold
exchanged IF's
sub get_net_IFnames_hwaddrs () { # get names +
addrs from /sys
vrfy_drivers
array pseudo_devs=(br bond ifb team)
string pseudo_RE="^+(${pseudo_devs[@]})$"
pseudo_RE=${pseudo_RE// /|}
string netdev_pat="+([_0-9a-z])+([0-9])"
( cd "$sysnet" &&
for nm in $( echo $netdev_pat); do
[[ $pseudo_re =~ $nm ]] && continue
hwaddr="$(<$nm/address)"
echo "$nm" "$(<$nm/address)"
done )
}
sub read_actuals () {
# parse output stream from above
my ifname hwaddr
while read ifname hwaddr; do
act_hw2if[$hwaddr]="$ifname"
act_if2hw["$ifname"]="$hwaddr"
done < <(get_net_IFnames_hwaddrs)
}
sub ifaddr_cmd () {
if ((${#act_hw2if[@]:-0}==0)) ;then read_actuals; fi
my hwaddr
for ifname in $(printf "%s\n" "${act_hw2if[@]}"|sort|tr "\n" " ") ; do
my first_ifn="$ifname"
if [[ $ifname =~ \+ ]] ; then
first_ifn="${ifname%%+*}"
fi
printf "%s\t%s\n" "$ifname" "${act_if2hw["$first_ifn"]}"
done
}
sub ifmap_cmd () {
ifaddr_cmd "$@"
}
sub remap_cmd () {
# remap devnames if needed
if ((${#act_hw2if[@]}==0)); then read_actuals; fi
my key ifname
int count=0
array ifnames=$(printf "%s\n" "${!if2hw[@]}"|sort|
grep -P
'^[^~+]*$' |tr "\n" " ")
array rev_ifns=($(rev "${ifnames[@]}" ))
for key in "${rev_ifns[@]}"; do
int is_regex=0;
ifname="$key"
if [[ ${key:0:1} == ~ ]];then ifname=${key:1}; is_regex=1; fi
my hwaddr="${if2hw["$key"]:-""}"
my actual_hw="${act_if2hw["$ifname"]:-""}"
my actual_if="${act_hw2if["$actual_hw"]:-""}"
##line 233
if [[ ${actual_hw:-""} && ! $actual_hw =~ \+ ]]; then
##
if ((is_regex)); then [[ $actual_hw =~ $hwaddr ]] &&
continue
else [[ $actual_hw == $hwaddr ]] && continue; fi
if [[ ! ${act_if2hw["$ifname"]:-} ]]; then
#Nobody has the name, use it
down_if "$actual_hw"
rename_if "$actual_hw" "$ifname" ; count+=1
else
rename_if "$actual_if" "X$ifname"; #don't
count temp renames 2x
XIF["X$ifname"]="$hwaddr"
fi
fi
done
if ((${#XIF[@]}==0)); then
echo "HW interfaces appear to be in order."; return 0; fi
int count=0
for ifname in "${!XIF[@]}"; do
hwaddr=${XIF[$ifname]};
ifname=${ifname#X}
my destname=${hw2if[$hwaddr]}
rename_if "$ifname" "$destname" ; count+=1
done
printf "%d interface%s renamed\n" $count "$( (($count!=1)) && echo "s"
)"
}
sub start_cmd () {
remap_cmd "$@"
}
hash switches=([ifmap]=1 [remap]=1 [start]=1)
sub help () {
echo "$_prg:"
echo "Options: ifmap - show current hw# -> IF map"
echo " remap - verify & remap ifnames if needed"
return 1
}
if (($#)) ; then
dcl op="${1#:-}"
if [[ ${switches[$op]:-} ]]; then
cmd="${op}_cmd"
shift
$cmd "$@"
else
echo "Unknown switch :-$op"
fi
else
help
fi
# vim: ts=2 sw=2 number fdm=marker fdc=1
#/etc/sysconfig/assign_netif_names - sample config
# to be sourced by BASH
######
# assign_netif_names reads this at boot to learn of a users
# desired network naming (and ordering)
#needed_drivers=(e1000e bnx2 ixgbe) # (list builtin as well as modules)
# Note -- using brace_expansions
#Linknames=( $(echo eth{0..5}) )
# Links that we _expect_ will come up with right names (built-mods)
#Default_good=( $(echo eth{0..1}) )
# store as hash, with intfname as key and it's ethernet addr as the data
# if2hw=([eth0]="00:15:17:bf:be:b2" [eth1]="00:15:17:bf:be:b3"
# [eth2]="00:26:b9:48:71:e2"
[eth3]="00:26:b9:48:71:e4"
# [eth4]="a0:36:9f:15:c9:c0"
[eth5]="a0:36:9f:15:c9:c2" )
- Re: bash uses tmp files for inter-process communication instead of pipes?, (continued)
- Re: bash uses tmp files for inter-process communication instead of pipes?, Pierre Gaston, 2014/10/06
- Re: bash uses tmp files for inter-process communication instead of pipes?, Greg Wooledge, 2014/10/06
- Re: bash uses tmp files for inter-process communication instead of pipes?, Linda Walsh, 2014/10/06
- Re: bash uses tmp files for inter-process communication instead of pipes?, Greg Wooledge, 2014/10/06
- Re: bash uses tmp files for inter-process communication instead of pipes?, Linda Walsh, 2014/10/06
- Re: bash uses tmp files for inter-process communication instead of pipes?, Linda Walsh, 2014/10/06
- Re: bash uses tmp files for inter-process communication instead of pipes?, Greg Wooledge, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Linda Walsh, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Greg Wooledge, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Pierre Gaston, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?,
Linda Walsh <=
- Re: bash uses tmp files for inter-process communication instead of pipes?, Greg Wooledge, 2014/10/08
- Re: bash uses tmp files for inter-process communication instead of pipes?, Linda Walsh, 2014/10/09
- Re: bash uses tmp files for inter-process communication instead of pipes?, Chet Ramey, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Linda Walsh, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Chet Ramey, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Pierre Gaston, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Linda Walsh, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Dave Rutherford, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Dave Rutherford, 2014/10/07
- Re: bash uses tmp files for inter-process communication instead of pipes?, Chet Ramey, 2014/10/07