Unix: Using date in alias doesn't output the current date/time - unix

In my bash_profile, I'm referencing an external alias.sh file, which has the following alias:
alias date="echo `date "+%Y-%m-%d at %H:%M":%S`"
If I issue date in a new terminal session, it constantly outputs the specific date at the time when the alias.sh file was sourced (i.e. when I started the new session) …
How do I make an alias that actually outputs the current date, when executing the aliased command?

Uhh, why not just?
alias date='date "+%Y-%m-%d at %H:%M":%S'
No need to echo it. When you use the backwards tick ( ` ), whatever's in it gets evaluated when alias.sh is sourced.

you can place a backslash character in front of each backquote character. :
sysadmin#localhost:~$ alias p=\'date\'
sysadmin#localhost:~$ p
Tue Apr 4 13:17:57 UTC 2017
sysadmin#localhost:~$ echo Today is $(p)
Today is Tue Apr 4 13:19:18 UTC 2017

Add this to your ~/.aliases file:
alias cd 'cd \!* ; set prompt = "\n`/bin/pwd`\n:%{^[];%~^G%}%{^[[0;37m%}(%{^[[1;36m%}%p%{^[[0;37m%})%{^[[0;35m%}%m%{^[[0;37m%}%{^[[0;33m%}>%{^[[0;37;37m%}:\n`/usr/bin/whoami`>>>>>>>>>>>>>>>> "'
Then run $source ~/.aliases

Related

RHL5 to Sunsolaries

Below code works in bash but it is not working in ksh.
Presently i am using RHL5 version os below code is working fine but in sunsolaries it is not working.
In sunsolaries we are using Korn Shell.
#!/bin/bash
#give start date and enddate in the format yyyy_mm_dd
startdate="${1//_/-}" # change underscores into dashes
enddate="${2//_/-}"
enddate=`date -d "$enddate + $i day" "+%Y_%m_%d"` #Increases enddate by 1 day so that loop runs on given enddate also
enddate="${enddate//_/-}"
echo "StartDate: $startdate EndDate+1Day: $enddate"
nextdate=$startdate #nextdate runs from startdate to enddate
while [ 1 ]
do
echo "$nextdate $enddate"
if [ "$nextdate" == "$enddate" ];then #after given enddate loop breaks
break
fi
day=`date -d "$nextdate"`
arr=(${day// / })
echo "${arr[0]}"
if [ "${arr[0]}" == "Sat" ];then #checking if day is Saturday, if true then increase nextday and continue
nextdate=`date -d "$nextdate + 1 day" "+%Y_%m_%d"`
nextdate="${nextdate//_/-}"
continue
fi
#####your code begins here
echo "creating file file_$nextdate.txt"
touch "file_$nextdate.txt" #test code, just creating files with date, remove this
#####your code ends here
nextdate=`date -d "$nextdate + 1 day" "+%Y_%m_%d"` #increasing nextday by 1 day
nextdate="${nextdate//_/-}"
done
Please help me how it works in ksh
Thanks
Your script is using several time the Gnu date specific -d option. Either find a different way to achieve what it does in you use case, or install Gnu date on the Solaris machine if it isn't already.

zsh: update prompt with current time when a command is started

I have a zsh prompt I rather like: it evaluates the current time in precmd and displays that on the right side of the prompt:
[Floatie:~] ^_^
cbowns% [9:28:31 on 2012-10-29]
However, this isn't exactly what I want: as you can see below, this time is actually the time the previous command exited, not the time the command was started:
[Floatie:~] ^_^
cbowns% date [9:28:26 on 2012-10-29]
Mon Oct 29 09:28:31 PDT 2012
[Floatie:~] ^_^
cbowns% date [9:28:31 on 2012-10-29]
Mon Oct 29 09:28:37 PDT 2012
[Floatie:~] ^_^
cbowns% [9:28:37 on 2012-10-29]
Is there a hook in zsh to run a command just before the shell starts a new command so I can update the prompt timestamp then? (I saw Constantly updated clock in zsh prompt?, but I don't need it constantly updated, just updated when I hit enter.)
(The ^_^ is based on the previous command's return code. It shows ;_; in red when there's a nonzero exit status.)
This is in fact possible without resorting to strange hacks. I've got this in my .zshrc
RPROMPT='[%D{%L:%M:%S %p}]'
TMOUT=1
TRAPALRM() {
zle reset-prompt
}
The TRAPALRM function gets called every TMOUT seconds (in this case 1), and here it performs a prompt refresh, and does so until a command starts execution (and it doesn't interfere with anything you type on the prompt before hitting enter). I know you don't need it constantly refreshed but it still gets the job done without needing a line for itself!
Source: http://www.zsh.org/mla/users/2007/msg00944.html (It's from 2007!)
I had a struggle to make this:
It displays the date on the right side when the command has been executed.
It does not overwrite the command shown.
Warning: it may overwrite the current RPROMPT.
strlen () {
FOO=$1
local zero='%([BSUbfksu]|([FB]|){*})'
LEN=${#${(S%%)FOO//$~zero/}}
echo $LEN
}
# show right prompt with date ONLY when command is executed
preexec () {
DATE=$( date +"[%H:%M:%S]" )
local len_right=$( strlen "$DATE" )
len_right=$(( $len_right+1 ))
local right_start=$(($COLUMNS - $len_right))
local len_cmd=$( strlen "$#" )
local len_prompt=$(strlen "$PROMPT" )
local len_left=$(($len_cmd+$len_prompt))
RDATE="\033[${right_start}C ${DATE}"
if [ $len_left -lt $right_start ]; then
# command does not overwrite right prompt
# ok to move up one line
echo -e "\033[1A${RDATE}"
else
echo -e "${RDATE}"
fi
}
Sources:
http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html
https://stackoverflow.com/a/10564427/238913
You can remap the Return key to reset the prompt before accepting the line:
reset-prompt-and-accept-line() {
zle reset-prompt
zle accept-line
}
zle -N reset-prompt-and-accept-line
bindkey '^m' reset-prompt-and-accept-line
zsh will run the preexec function just before executing a line. It would be simple to have that output the current time, a simple version would be just:
preexec() { date }
Modifying an existing prompt would be much more challenging.
Building off #vitaŭt-bajaryn's cool ZSH style answer:
I think overriding the accept-line function is probably the most idiomatic zsh solution:
function _reset-prompt-and-accept-line {
zle reset-prompt
zle .accept-line # Note the . meaning the built-in accept-line.
}
zle -N accept-line _reset-prompt-and-accept-line
You can use ANSI escape sequences to write over the previous line, like this:
preexec () {
DATE=`date +"%H:%M:%S on %Y-%m-%d"`
C=$(($COLUMNS-24))
echo -e "\033[1A\033[${C}C ${DATE} "
}

How can I assign command output to a variable in GNU make target rule?

At a BASH prompt, I can do the following:
~/repo$ HISTORY_LOG=$(git log $(get_old_version)..$(get_new_version)); [[ ! -z ${HISTOR_LOG} ]] && ( echo "Some header"; echo "${HISTORY_LOG}" )
Where git log is demonstrably simplified version of what I actually have.
In a make file I have the following command as part of a target:
$(OUTPUT): $(INPUT)
...
echo "Some header" > $(LOG_FILE)
git log $(shell get_old_version)..$(shell get_new_version) >> $(LOG_FILE)
How can I rewrite the make target to behave like the bash command?
If I do the following line-feeds are being stripped:
$(OUTPUT): $(INPUT)
...
HISTORY_LOG="$(shell git log $(shell get_old_version)..$(shell get_new_version))" ; \
[ -z "$${HISTORY_LOG}" ] && \
true || \
(echo "Some header" ; echo "$${HISTORY_LOG}" )
when run looks like:
~/repo $ make
commit 2b4d87b0e64d129028c1a7a0b46ccde2f42c5e93 Author: Jamie <Jamie#mymail.com> Date: Mon Jun 25 18:46:27 2012 -0400 Issue #468: This sucker's been sped up.
and what I prefer would be:
~/repo $ make
commit 2b4d87b0e64d129028c1a7a0b46ccde2f42c5e93
Author: Jamie <Jamie#mymail.com>
Date: Mon Jun 25 18:46:27 2012 -0400
Issue #468: This sucker's been sped up.
I think the issue is the that make executes commands in /bin/sh and not /bin/bash. Regardless I'm looking for a portable solution if there is one.
Make's shell is eating your newlines. Just stop using it. Instead of $( shell get_old_version ), escape the $:
$$( get_old_version )

Check the date and time entered by user in UNIX

I have a Shell script which uses the date and time parameters entered by the user.
Date as mm/dd/yyyy and Time as HH:MM .
What would be the easiest means to check the user had entered the proper date [ like month should be less than 12.... for time MM should be less than 60...
Do we have any built in functions in UNIX for checking the timestamp?
You could use the unix date tool to parse and verify it for you, and test the return code e.g.
A valid date, return code of 0:
joel#bohr:~$ date -d "12/12/2000 13:00"
Tue Dec 12 13:00:00 GMT 2000
joel#bohr:~$ echo $?
0
An invalid date, return code 1:
joel#bohr:~$ date -d "13/12/2000 13:00"
date: invalid date `13/12/2000 13:00'
joel#bohr:~$ echo $?
1
You can vary the input format accepted by date by using the +FORMAT option (man date)
Putting it all together as a little script:
usrdate=$1
date -d "$usrdate" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Date $usrdate was valid"
else
echo "Date $usrdate was invalid"
fi
You could use grep to check that the input conforms to the correct format:
if ! echo "$INPUT" | grep -q 'PATTERN'; then
# handle input error
fi
where PATTERN is a regular expressino that matches all valid inputs and only valid inputs. I leave constructing that pattern to you ;-).
(Late answer)
Something that you can use:
...
DATETIME=$1
#validate datetime..
tmp=`date -d "$DATETIME" 2>&1` ; #return is: "date: invalid date `something'"
if [ "${tmp:6:7}" == "invalid" ]; then
echo "Invalid datetime: $DATETIME" ;
else
... valid datetime, do something with it ...
fi

Converting dates in AWK

I have a file containing many columns of text, including a timestamp along the lines of Fri Jan 02 18:23 and I need to convert that date into MM/DD/YYYY HH:MM format.
I have been trying to use the standard `date' tool with awk getline to do the conversion, but I can't quite figure out how to pass the fields into the 'date' command in the format it expects (quoted with " or 's,) as getline needs the command string enclosed in quotes too.
Something like "date -d '$1 $2 $3 $4' +'%D %H:%M'" | getline var
Now that I think about it, I guess what I'm really asking is how to embed awk variables into a string.
If you're using gawk, you don't need the external date which can be expensive to call repeatedly:
awk '
BEGIN{
m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
for(o=1;o<=m;o++){
months[d[o]]=sprintf("%02d",o)
}
format = "%m/%d/%Y %H:%M"
}
{
split($4,time,":")
date = (strftime("%Y") " " months[$2] " " $3 " " time[1] " " time[2] " 0")
print strftime(format, mktime(date))
}'
Thanks to ghostdog74 for the months array from this answer.
you can try this. Assuming just the date you specified is in the file
awk '
{
cmd ="date \"+%m/%d/%Y %H:%M\" -d \""$1" "$2" "$3" "$4"\""
cmd | getline var
print var
close(cmd)
}' file
output
$ ./shell.sh
01/02/2010 18:23
and if you are not using GNU tools, like if you are in Solaris for example, use nawk
nawk 'BEGIN{
m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
for(o=1;o<=m;o++){
months[d[o]]=sprintf("%02d",o)
}
cmd="date +%Y"
cmd|getline yr
close(cmd)
}
{
day=$3
mth=months[$2]
print mth"/"day"/"yr" "$4
} ' file
I had a similar issue converting a date from RRDTool databases using rrdfetch but prefer one liners that I've been using since Apollo computer days.
Data looked like this:
localTemp rs1Temp rs2Temp thermostatMode
1547123400: 5.2788174937e+00 4.7788174937e+00 -8.7777777778e+00 2.0000000000e+00
1547123460: 5.1687014581e+00 4.7777777778e+00 -8.7777777778e+00 2.0000000000e+00
One liner:
rrdtool fetch -s -14400 thermostatDaily.rrd MAX | sed s/://g | awk '{print "echo ""\`date -r" $1,"\`" " " $2 }' | sh
Result:
Thu Jan 10 07:25:00 EST 2019 5.3373432378e+00
Thu Jan 10 07:26:00 EST 2019 5.2788174937e+00
On the face of it this doesn't look very efficient to me but this kind of methodology has always proven to be fairly low overhead under most circumstances even for very large files on very low power computer (like 25Mhz NeXT Machines). Yes Mhz.
Sed deletes the colon, awk is used to print the other various commands of interest including just echoing the awk variables and sh or bash executes the resulting string.
For methodology or large files or streams I just head the first few lines and gradually build up the one liner. Throw away code.

Resources