Cronjob missing content from mail body, manually works fine - bash

Edit: Solution found via Barmar's answer. Added full smartctl command path and it works via crontab now.
I have the below script:
#!/bin/bash
#set -x
EMAIL="admin#domain.co.uk"
FILE="/root/scripts/hddreport.txt"
HOST=`hostname`
HDD01="/dev/sda"
P=`ping -c 1 $HOST | sed '1 ! d' | awk '{print $3}'`
cd /root/scripts/
echo -en "HDD health check on the server hosting" $HOST $P > $FILE
echo -e "\n" >> $FILE
smartctl -H $HDD01 >> $FILE
# The above commands do correctly write the content to $FILE (proved by removing the rm command at the bottom and doing cat on the file after)
smartctl -H $HDD01
echo "\nEmailed you the health of the Hard Drive $HDD01\n"
mailx -s "HDD health check complete on `date`" $EMAIL < $FILE
rm $FILE
which runs fine by doing bash /root/scripts/diskhealth.sh as it shows this in my mailbox:
HDD health check on the server hosting domain.co.uk (0.0.0.0)
smartctl 5.40 2010-07-12 r3124 [x86_64-unknown-linux-gnu] (local build)
Copyright (C) 2002-10 by Bruce Allen, http://smartmontools.sourceforge.net
SMART Health Status: OK
But when I let it run via crontab using any of the following syntax:
X 20 * * * /bin/bash /root/scripts/diskhealth.sh
X 20 * * * /bin/sh /root/scripts/diskhealth.sh
X 20 * * * /root/scripts/diskhealth.sh
it puts everything but the smartctl disk check:
HDD health check on the server hosting domain.co.uk (0.0.0.0)
Here's what it shows if I add extra echo lines:
This is a test
HDD health check on the server hosting domain.co.uk (0.0.0.0)
Amended script for "This is a test" below:
#!/bin/bash
#set -x
EMAIL="admin#domain.co.uk"
FILE="/root/scripts/hddreport.txt"
HOST=`hostname`
HDD01="/dev/sda"
P=`ping -c 1 $HOST | sed '1 ! d' | awk '{print $3}'`
cd /root/scripts/
echo "This is a test" > $FILE
echo -en "HDD health check on the server hosting" $HOST $P >> $FILE
echo -e "\n" >> $FILE
smartctl -H $HDD01 >> $FILE
smartctl -H $HDD01
echo "\nEmailed you the health of the Hard Drive $HDD01\n"
mailx -s "HDD health check complete on `date`" $EMAIL < $FILE
rm $FILE
Here is the /var/log/syslog output from cron:
Jun 6 20:25:01 hostname /USR/SBIN/CRON[1018112]: (root) CMD (bash /root/scripts/diskhealth.sh)
Jun 6 20:25:01 hostname postfix/pickup[1016576]: 5740356613F: uid=0 from=<root>
Jun 6 20:25:01 hostname postfix/cleanup[1018125]: 5740356613F: message-id=<20130606192501.5740356613F#hostname>
Jun 6 20:25:01 hostname postfix/qmgr[292015]: 5740356613F: from=<root#hostname>, size=465, nrcpt=1 (queue active)
Jun 6 20:25:01 hostname postfix/pickup[1016576]: 631F156613E: uid=0 from=<root>
Jun 6 20:25:01 hostname postfix/cleanup[1018125]: 631F156613E: message-id=<20130606192501.631F156613E#hostname>
Jun 6 20:25:01 hostname postfix/qmgr[292015]: 631F156613E: from=<root#hostname>, size=759, nrcpt=1 (queue active)
Jun 6 20:25:01 hostname pvemailforward[1018132]: forward mail to <root#localhost.localdomain>
Jun 6 20:25:01 hostname postfix/pickup[1016576]: B597B566148: uid=65534 from=<nobody>
Jun 6 20:25:01 hostname postfix/cleanup[1018125]: B597B566148: message-id=<20130606192501.631F156613E#hostname>
Jun 6 20:25:01 hostname postfix/local[1018131]: 631F156613E: to=<root#hostname>, orig_to=<root>, relay=local, delay=0.39, delays=0.16/0/0/0.23, dsn=2.0.0, status=sent (delivered to command: /usr/bin/pvemailforward)
Jun 6 20:25:01 hostname postfix/qmgr[292015]: 631F156613E: removed
Jun 6 20:25:01 hostname postfix/qmgr[292015]: B597B566148: from=<nobody#hostname>, size=963, nrcpt=1 (queue active)
Jun 6 20:25:01 hostname postfix/smtp[1018135]: B597B566148: to=<root#localhost.localdomain>, relay=none, delay=0.16, delays=0.12/0/0.04/0, dsn=5.4.4, status=bounced (Host or domain name not found. Name service error for name=localhost.localdomain type=A: Host not found)
Jun 6 20:25:01 hostname postfix/qmgr[292015]: B597B566148: removed
Jun 6 20:25:01 hostname postfix/cleanup[1018125]: D6570566147: message-id=<20130606192501.D6570566147#hostname>
Jun 6 20:25:01 hostname postfix/smtp[1018130]: 5740356613F: to=<admin#domain.co.uk>, relay=ASPMX.L.GOOGLE.COM[173.194.67.27]:25, delay=0.68, delays=0.12/0/0.19/0.36, dsn=2.0.0, status=sent (250 2.0.0 OK 1370546701 iy4si8635735wic.1 - gsmtp)
Jun 6 20:25:01 ds9453 postfix/qmgr[292015]: 5740356613F: removed
The email is received, just missing the smartctl output.

Cron jobs don't run your .profile. So if smartctl is in a directory you add to $PATH in your profile, it won't be found when you run via cron. Try using the full pathname to the command.

Related

unbound variable when run a crontab task in mac os x

when I run script in mac os x like this:
*/1 * * * * /Users/dolphin/Library/"Mobile Documents"/com~apple~CloudDocs/Document/source/dolphin/dolphin-scripts/bash/cron/latex_compile_alive_monitor.sh >> /Users/dolphin/shell.log
the output is:
From dolphin#dolphins-MacBook-Pro.local Tue Jan 21 20:47:01 2020
Return-Path: <dolphin#dolphins-MacBook-Pro.local>
X-Original-To: dolphin
Delivered-To: dolphin#dolphins-MacBook-Pro.local
Received: by dolphins-MacBook-Pro.local (Postfix, from userid 501)
id 7430417C4C19; Tue, 21 Jan 2020 20:47:00 +0800 (CST)
From: dolphin#dolphins-MacBook-Pro.local (Cron Daemon)
To: dolphin#dolphins-MacBook-Pro.local
Subject: Cron <dolphin#dolphins-MacBook-Pro> /Users/dolphin/Library/"Mobile Documents"/com~apple~CloudDocs/Document/source/dolphin/dolphin-scripts/bash/cron/latex_compile_alive_monitor.sh >> /Users/dolphin/shell.log
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=dolphin>
X-Cron-Env: <USER=dolphin>
X-Cron-Env: <HOME=/Users/dolphin>
Message-Id: <20200121124701.7430417C4C19#dolphins-MacBook-Pro.local>
Date: Tue, 21 Jan 2020 20:47:00 +0800 (CST)
+ BOOK_PATH='/Users/dolphin/Library/Mobile Documents/com~apple~CloudDocs/Document/source/dolphin/summary/'
+ COMMAND='/Library/TeX/texbin/latexmk -pdfxe -pvc -xelatex -interaction=nonstopmode '
+ PROCESS_NAME_KEYWORDS_MAP=(["dolphin-book-2020.tex"]="${COMMAND} ./dolphin-book-2020/dolphin-book-2020.tex" ["the-book-of-mine.tex"]="${COMMAND} ./the-books-of-mine/the-book-of-mine.tex" ["kubelet-learn.tex"]="${COMMAND} ./kubelet-learn/kubelet-learn.tex")
/Users/dolphin/Library/Mobile Documents/com~apple~CloudDocs/Document/source/dolphin/dolphin-scripts/bash/cron/latex_compile_alive_monitor.sh: line 15: dolphin: unbound variable
which variable was unboud? COMMAND? I am already defined in script.this is my script:
#!/usr/bin/env bash
# 当使用未初始化的变量时,程序自动退出
set -u
# 当任何一行命令执行失败时,自动退出脚本
set -e
# 在运行结果之前,先输出执行的那一行命令
set -x
BOOK_PATH="/Users/dolphin/Library/Mobile Documents/com~apple~CloudDocs/Document/source/dolphin/summary/"
COMMAND="/Library/TeX/texbin/latexmk -pdfxe -pvc -xelatex -interaction=nonstopmode "
declare -A PROCESS_NAME_KEYWORDS_MAP=(
["dolphin-book-2020.tex"]="${COMMAND} ./dolphin-book-2020/dolphin-book-2020.tex"
["the-book-of-mine.tex"]="${COMMAND} ./the-books-of-mine/the-book-of-mine.tex"
["kubelet-learn.tex"]="${COMMAND} ./kubelet-learn/kubelet-learn.tex"
)
cd "${BOOK_PATH}"
for key in ${!PROCESS_NAME_KEYWORDS_MAP[#]}
do
PID_COUNT=`ps -ef | grep "${key}" | grep -v "grep" | wc -l`
if [[ ${PID_COUNT} -lt 1 ]]; then
nohup `${PROCESS_NAME_KEYWORDS_MAP[${key}]}` &
else
echo "process already exists..."
fi
done
maybe remove the space in the end of COMMAND

EC2 userdata script runs very slowly on Centos7 AMI

There appears to be a 25 second delay every time a userdata script touches the disk on the centos 7 AMI from AWS marketplace.
Here's my script:
#!/bin/bash -ex
echo "[TIMER] START $(date +%s.%N)"
current_user=$(whoami)
echo "Running as: $current_user"
sudo id -u myuser &>/dev/null || sudo useradd myuser
echo "[TIMER] CreatedUser $(date +%s.%N)"
time sudo yum update -y
echo "[TIMER] Yum Update $(date +%s.%N)"
sudo mkdir -p /opt/myuser/resources
echo "[TIMER] Create /opt/myuser/resources $(date +%s.%N)"
sudo bash -c "cat > /etc/systemd/system/my-service.service" <<EOF
[Unit]
Description=My Service
After=network-online.target
[Service]
User=myuser
Group=myuser
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -ex -c 'echo "Hello World"'
[Install]
Alias=my-service
WantedBy=default.target
EOF
echo "[TIMER] Make my-service.service $(date +%s.%N)"
sudo chmod 644 /etc/systemd/system/my-service.service
echo "[TIMER] Chmod $(date +%s.%N)"
sudo systemctl daemon-reload
echo "[TIMER] daemon-reload $(date +%s.%N)"
sudo systemctl enable my-service
echo "[TIMER] enable $(date +%s.%N)"
sudo systemctl start my-service
echo "[TIMER] END: my-service $(date +%s.%N)"
I launch a c5.large of this AMI and use the above as my userdata script: https://aws.amazon.com/marketplace/pp/B00O7WM7QW
Timers result:
[TIMER] START 1546978269.809559549
[TIMER] CreatedUser 1546978320.472706964
[TIMER] Yum Update 1546978356.991642552
[TIMER] Create /opt/myuser/resources 1546978382.033044767
[TIMER] Make my-service.service 1546978407.074353857
[TIMER] Chmod 1546978432.111791937
[TIMER] daemon-reload 1546978457.195078083
[TIMER] enable 1546978482.265036318
[TIMER] END: my-service 1546978507.313735938
| CENTOS 7 | | |
|-----------------------------------------------------------|----------------------|-------------|
| | | |
| log | timestamp | seconds |
| [TIMER] START 1546978269.809559549 | 1546978269.809559549 | |
| [TIMER] CreatedUser 1546978320.472706964 | 1546978320.472706964 | 50.66315007 |
| [TIMER] Yum Update 1546978356.991642552 | 1546978356.991642552 | 36.51893997 |
| [TIMER] Create /opt/myuser/resources 1546978382.033044767 | 1546978382.033044767 | 25.04139996 |
| [TIMER] Make my-service.service 1546978407.074353857 | 1546978407.074353857 | 25.04131007 |
| [TIMER] Chmod 1546978432.111791937 | 1546978432.111791937 | 25.03743982 |
| [TIMER] daemon-reload 1546978457.195078083 | 1546978457.195078083 | 25.08328009 |
| [TIMER] enable 1546978482.265036318 | 1546978482.265036318 | 25.06995988 |
| [TIMER] END: my-service 1546978507.313735938 | 1546978507.313735938 | 25.04870009 |
| | | |
| | total (s) | 237.50418 |
| | | |
| | total (m) | 3.958402999 |
If you scroll to the right in my ASCII table you can see that simple commands like mkdir, chmod, and useradd are taking 25 seconds. Why does this happen?
EDIT:
contents of /etc/hosts
$ hostname
ip-172-31-40-213.us-west-2.compute.internal
$ cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
example log from /var/log/messages, the systemd logs show that creating the sudo session takes the 25 seconds:
Jan 9 23:50:32 ip-172-31-35-166 cloud-init: + echo '[TIMER] Make my-service.service 1547077832.899069408'
Jan 9 23:50:32 ip-172-31-35-166 cloud-init: [TIMER] Make my-service.service 1547077832.899069408
Jan 9 23:50:32 ip-172-31-35-166 cloud-init: + sudo chmod 644 /etc/systemd/system/my-service.service
Jan 9 23:50:32 ip-172-31-35-166 systemd: Removed slice User Slice of root.
Jan 9 23:50:32 ip-172-31-35-166 systemd: Created slice User Slice of root.
Jan 9 23:50:32 ip-172-31-35-166 systemd: Started Session c3 of user root.
Jan 9 23:50:57 ip-172-31-35-166 cloud-init: ++ date +%s.%N
Jan 9 23:50:57 ip-172-31-35-166 cloud-init: + echo '[TIMER] Chmod 1547077857.946078493'
Jan 9 23:50:57 ip-172-31-35-166 cloud-init: [TIMER] Chmod 1547077857.946078493
journalctl log shows the likely culprit:
Jan 09 23:50:32 ip-172-31-35-166.us-west-2.compute.internal cloud-init[1197]: + echo '[TIMER] Make my-service.service 1547077832.899069408'
Jan 09 23:50:32 ip-172-31-35-166.us-west-2.compute.internal cloud-init[1197]: [TIMER] Make my-service.service 1547077832.899069408
Jan 09 23:50:32 ip-172-31-35-166.us-west-2.compute.internal cloud-init[1197]: + sudo chmod 644 /etc/systemd/system/my-service.service
Jan 09 23:50:32 ip-172-31-35-166.us-west-2.compute.internal systemd[1]: Removed slice User Slice of root.
Jan 09 23:50:32 ip-172-31-35-166.us-west-2.compute.internal sudo[13392]: root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/bin/chmod 644 /etc/systemd/system/my-service.service
Jan 09 23:50:32 ip-172-31-35-166.us-west-2.compute.internal systemd[1]: Created slice User Slice of root.
Jan 09 23:50:32 ip-172-31-35-166.us-west-2.compute.internal systemd[1]: Started Session c3 of user root.
Jan 09 23:50:57 ip-172-31-35-166.us-west-2.compute.internal sudo[13392]: pam_systemd(sudo:session): Failed to create session: Connection timed out
Jan 09 23:50:57 ip-172-31-35-166.us-west-2.compute.internal sudo[13392]: pam_unix(sudo:session): session opened for user root by (uid=0)
Jan 09 23:50:57 ip-172-31-35-166.us-west-2.compute.internal sudo[13392]: pam_unix(sudo:session): session closed for user root
Jan 09 23:50:57 ip-172-31-35-166.us-west-2.compute.internal cloud-init[1197]: ++ date +%s.%N
Jan 09 23:50:57 ip-172-31-35-166.us-west-2.compute.internal cloud-init[1197]: + echo '[TIMER] Chmod 1547077857.946078493'
Jan 09 23:50:57 ip-172-31-35-166.us-west-2.compute.internal cloud-init[1197]: [TIMER] Chmod 1547077857.946078493
Googling more, I find: https://github.com/systemd/systemd/issues/2863
This has been fixed in a later version of systemd but centos on AWS EC2 comes with systemd version 219 and I can't really update it myself. Any suggestions? Is there some config I can place to avoid this issue? I can remove most instances of sudo in my userdata script but I do need it for things like:
sudo -H -u myuser bash -ex <<EOF
... commands
EOF
FWIW Amazon Linux 2 comes with the same version of systemd but does not exhibit this behavior.
Issue and solution is noted in Redhat's link here:
https://access.redhat.com/solutions/5692661
In summary, it's not normal to run commands as sudo in a userdata script, thus the default policy is to not allow this, which causes a 25sec delay while it attempts to run pam_systemd and times out due to the dbus 25sec timeout.
In my case I was attempting to run su <user> -c "command". My error was found by running journalctl -b (-b is for current boot session). And you can find the related error log like:
pam_systemd(su:session): Failed to create session: Connection time out

expect redirect outputs giberish

I have backup.sh
#!/bin/bash
expect backup.exp
and backup.exp
#!/usr/bin/expect -f
#exp_internal 1
#log_user 0
set timeout 29
puts "----------------- [exec date +%Y.%m.%d\ %H:%M:%S] ------ exp start -----"
spawn -noecho ssh andrej#10.11.22.17
expect {
timeout { send_user "\n--- failed to get expected string---\n"; exit 1 }
eof { send_user "\nSSH failure\n"; exit 1 }
" andrej $ "
}
send "sudo bash\r"
send "ls -lh\r"
send exit\r
send exit\r
interact
puts "----------------- [exec date +%Y.%m.%d\ %H:%M:%S] ------ exp ende ------"
when I run
bash backup.sh >> backup.templog 2>&1
I get
----------------- 2015.09.02 18:48:29 ------ exp start -----
Last login: Wed Sep 2 18:48:24 2015 from 10.11.22.16
^[]0;andrej#centos7c:~/andrej^G^[[?1034h^[[01;32mandrej#centos7c ^[[01;34m18:48 andrej $ ^[[00msudo bash
^[]0;root#centos7c:/home/andrej/andrej^G^[[?1034h^[[01;31mroot#centos7c ^[[01;34m18:48 andrej $ ^[[00mls -lh
total 16K
-rw-rw-r--. 1 andrej andrej 13K Jun 30 19:04 iptables.sh
drwxrwxr-x. 2 andrej andrej 6 Jun 17 22:46 ^[[0m^[[01;34mmount^[[0m
^[]0;root#centos7c:/home/andrej/andrej^G^[[01;31mroot#centos7c ^[[01;34m18:48 andrej $ ^[[00mexit
exit
^[]0;andrej#centos7c:~/andrej^G^[[01;32mandrej#centos7c ^[[01;34m18:48 andrej $ ^[[00mexit
logout
Connection to 10.11.22.17 closed.
----------------- 2015.09.02 18:48:39 ------ exp ende ------
but when I do
bash backup.sh
, I get nice output that I need :
----------------- 2015.09.02 18:52:09 ------ exp start -----
Last login: Wed Sep 2 18:48:39 2015 from 10.11.22.16
andrej#centos7c 18:52 andrej $ sudo bash
root#centos7c 18:52 andrej $ ls -lh
total 16K
-rw-rw-r--. 1 andrej andrej 13K Jun 30 19:04 iptables.sh
drwxrwxr-x. 2 andrej andrej 6 Jun 17 22:46 mount
root#centos7c 18:52 andrej $ exit
exit
andrej#centos7c 18:52 andrej $ exit
logout
Connection to 10.11.22.17 closed.
----------------- 2015.09.02 18:52:20 ------ exp ende ------
How can I get rid of extra giberish when outputing to the log file when executing the script? I am using centos 7.1 in both server and client.
If you have any sugesstion please help me out. Thank you very much.
rewriting a but to address a couple of issues:
expect has 2 built-in methods to get the current datetime: timestamp (expect-specific) and clock (from Tcl)
I turn off output (log_user 0)
when it's important, I change the prompt and use an anchored regular expression to match it
I only output the results of the ls -lh command, which I suspect is your goal.
#!/usr/bin/expect -f
#exp_internal 1
set timeout 29
proc separator {msg} {
puts [format "----------------- %s ------ %s -----" [timestamp -format "%Y.%m.%d %T"] $msg]
}
separator "exp start"
log_user 0
spawn -noecho ssh andrej#10.11.22.17
expect {
timeout { send_user "\n--- failed to get expected string---\n"; exit 1 }
eof { send_user "\nSSH failure\n"; exit 1 }
" $ "
}
send "sudo bash\r"
expect " $ "
send "PS1='$'\r"
expect -re {\$$}
send "ls -lh\r"
expect -re {(.+)\r\n\$$}
puts $expect_out(1,string)
send "exit\r"
expect " $ "
send "exit\r"
expect eof
separator "exp ende"

cron task wouldn't work, why?

I want to write a cron task to record the ntpdate synchronization info into the system log, but there's no such info printed in the /var/log/messages after this cron task is done, where did I do wrong?
The followings are what my crontab looks like.
*/1 * * * * ntpdate 192.168.100.97 | logger -t "NTP"
*/1 * * * * echo "log test" | logger -t "TEST"
*/1 * * * * whoami | logger -t "WHO"
When I do tailf /var/log/messages and wait some time I only got the following lines, the NTP lines are missing.
Oct 29 15:22:01 localhost TEST: log test
Oct 29 15:22:01 localhost WHO: root
Oct 29 15:23:01 localhost TEST: log test
Oct 29 15:23:01 localhost WHO: root
Oct 29 15:24:01 localhost TEST: log test
Oct 29 15:24:01 localhost WHO: root
Oct 29 15:25:01 localhost TEST: log test
Oct 29 15:25:01 localhost WHO: root
Oct 29 15:26:01 localhost TEST: log test
Oct 29 15:26:01 localhost WHO: root
But when I do the ntpdate 192.168.100.97 | logger -t "NTP" in the command line, I could see there's message Oct 29 15:28:39 localhost NTP: 29 Oct 15:28:39 ntpdate[11101]: adjust time server 192.168.100.97 offset 0.000043 sec print out in the system log. What am I missing here?
Thanks in advance for your kind help.

How to decrease TCP connect() system call timeout?

In command below I enable file /dev/tcp/10.10.10.1/80 both for reading and writing and associate it with file descriptor 3:
$ time exec 3<>/dev/tcp/10.10.10.1/80
bash: connect: Operation timed out
bash: /dev/tcp/10.10.10.1/80: Operation timed out
real 1m15.151s
user 0m0.000s
sys 0m0.000s
This automatically tries to perform TCP three-way handshake. If 10.10.10.1 is not reachable as in example above, then connect system call tries to connect for 75 seconds. Is this 75 second timeout determined by bash? Or is this system default? Last but not least, is there a way to decrease this timeout value?
It's not possible in Bash without modifying the source as already mentioned, although here is the workaround by using timeout command, e.g.:
$ timeout 1 bash -c "</dev/tcp/stackoverflow.com/80" && echo Port open. || echo Port closed.
Port open.
$ timeout 1 bash -c "</dev/tcp/stackoverflow.com/81" && echo Port open. || echo Port closed.
Port closed.
Using this syntax, the timeout command will kill the process after the given time.
See: timeout --help for more options.
It is determined by TCP. It can be decreased on a per-socket basis by application code.
NB The timeout only takes effect if there is no response at all. If there is a connection refusal, the error occurs immediately.
No: there is no way of changing timeout by using /dev/tcp/
Yes, you could change default timeout for TCP connection in any programming language.
But, bash is not a programming language!
You could have a look into source code (see: Bash Homepage), you may find lib/sh/netopen.c file where you could read in _netopen4 function:
s = socket(AF_INET, (typ == 't') ? SOCK_STREAM : SOCK_DGRAM, 0);
You could read this file carefully, there are no consideration of connection timeout.
Without patching bash sources, there is no way of changing connection timeout by a bash script.
Simple HTTP client using netcat (near pure bash)
There is a little sample HTTP client written in pure bash, but using netcat:
#!/bin/bash
tmpfile=$(mktemp -p $HOME .netbash-XXXXXX)
exec 7> >(nc -w 3 -q 0 stackoverflow.com 80 >$tmpfile)
exec 6<$tmpfile
rm $tmpfile
printf >&7 "GET %s HTTP/1.0\r\nHost: stackoverflow.com\r\n\r\n" \
/questions/24317341/how-to-decrease-tcp-connect-system-call-timeout
timeout=100;
while ! read -t .001 -u 6 status ; do read -t .001 foo;done
echo STATUS: $status
[ "$status" ] && [ -z "${status//HTTP*200 OK*}" ] || exit 1
echo HEADER:
while read -u 6 -a head && [ "${head//$'\r'}" ]; do
printf "%-20s : %s\n" ${head%:} "${head[*]:1}"
done
echo TITLE:
sed '/<title>/s/<[^>]*>//gp;d' <&6
exec 7>&-
exec 6<&-
This could render:
STATUS: HTTP/1.1 200 OK
HEADER:
Cache-Control : private
Content-Type : text/html; charset=utf-8
X-Frame-Options : SAMEORIGIN
X-Request-Guid : 46d55dc9-f7fe-425f-a560-fc49d885a5e5
Content-Length : 91642
Accept-Ranges : bytes
Date : Wed, 19 Oct 2016 13:24:35 GMT
Via : 1.1 varnish
Age : 0
Connection : close
X-Served-By : cache-fra1243-FRA
X-Cache : MISS
X-Cache-Hits : 0
X-Timer : S1476883475.343528,VS0,VE100
X-DNS-Prefetch-Control : off
Set-Cookie : prov=ff1129e3-7de5-9375-58ee-5f739eb73449; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
TITLE:
bash - How to decrease TCP connect() system call timeout? - Stack Overflow
Some explanations:
We create first a temporary file (under private directory for security reason), bind and delete before using them.
$ tmpfile=$(mktemp -p $HOME .netbash-XXXXXX)
$ exec 7> >(nc -w 3 -q 0 stackoverflow.com 80 >$tmpfile)
$ exec 6<$tmpfile
$ rm $tmpfile
$ ls $tmpfile
ls: cannot access /home/user/.netbash-rKvpZW: No such file or directory
$ ls -l /proc/self/fd
lrwx------ 1 user user 64 Oct 19 15:20 0 -> /dev/pts/1
lrwx------ 1 user user 64 Oct 19 15:20 1 -> /dev/pts/1
lrwx------ 1 user user 64 Oct 19 15:20 2 -> /dev/pts/1
lr-x------ 1 user user 64 Oct 19 15:20 3 -> /proc/30237/fd
lr-x------ 1 user user 64 Oct 19 15:20 6 -> /home/user/.netbash-rKvpZW (deleted)
l-wx------ 1 user user 64 Oct 19 15:20 7 -> pipe:[2097453]
$ echo GET / HTTP/1.0$'\r\n\r' >&7
$ read -u 6 foo
$ echo $foo
HTTP/1.1 500 Domain Not Found
$ exec 7>&-
$ exec 6>&-

Resources