Crontab to create a new file - unix

I'm trying to create a simple crontab that creates a file called log.txt every minute by populating it with a simple command's output. Right now this is what I've put into my crontab:
* * * * * (/usr/bin/ls <pathToRandomDirectory) > log.txt
By my understanding, the 5 asterisks correspond to "every minute". But when I run this the log.txt file is not being created. Is there something I'm missing here?
ALSO, if I didn't want to have an email sent to me whenever the job is created I found that I need to put the line:
>/dev/null 2>&1
Somewhere in my crontab file. Where exactly does this go? At the end of the command or on a separate line?

You have to put an absolute path for log.txt. Otherwise, it will be created in /.
Also, >/dev/null 2>&1 has to be at the end of the sentence. If you want the 2 (meaning the errors) to be dismissed, just write 2>/dev/null.
Then, your final cronjob would be like this:
* * * * * /usr/bin/ls pathToRandomDirectory > /pathToRandomDirectory/log.txt 2>/dev/null

What exactly should be in that file? This creates a new file with the text "something" in it every minute:
* * * * * echo "something" > /path/to/your/file.txt
I had some problems with crontab especially when I created a new crontab config - my problem was that I had to insert an empty line at the end of the crontab - some systems need it to work correctly. So if you do
$ crontab -l
the output should be a list of your cron jobs on each line and then an empty line at the end.
Try it if it works for you. Sorry, but I'm not sure about the email, but I dont think that you need to put lines like that to crontab, play around with the configuration - it shouldn't send you any emails by default.

Related

Setup a cron for multiple commands in a single line

I execute a sh file using command ./abc.sh abc_config
How do we get this done via cron ? for a single command i usually do
5 0 * * * /test/abc.sh
But for ./abc.sh abc_config I am a little confused
One option could be to store the script and it's argument in another script and run that instead?
5 0 * * * /test/run_abc.sh
Contents of run_abc.sh
./abc.sh abc_config
You should possibly include paths and a "shebang" matching whatever shell you want to use, ie:
#!/usr/bin/env bash
/path-to-dir-where-program-is/abc.sh abc_config

Is it possible to use wild characters to delete dataset on z/OS

I want to remove lots of temporary PS datasets with dataset name like MYTEST.**, but still can't find an easy way to handle the task.
I meant to use a Shell command below to remove them
cat "//'dataset.list'"| xargs -I '{}' tsocmd "delete '{}'"
However, first I have to save the dataset list into a PS dataset or Unix file. In Unix, we can redirect output of ls command into a text file: "ls MYTEST.* > dslist", but on TSO or ISPF panel, seems no simple command to do that.
Anyone has any clue on this? Your comment would be appreciated.
Rexx ISPF option is probably the easiest and can be used in the future, but options include:
Use the save command in ispf 3.4 to save to a file, then use a rexx program on the file created by the save command
listcat command, in particular
listcat lvl(MYTEST) ofile(ddname)
then write a rexx program to do the actual delete
Alternatively you can use the ISPF services LMDINIT, LMDLISTY & LMDFREE in a rexx program running under ISPF i.e.
/* Rexx ispf program to process datasets */
Address ispexec
"LMDINIT LISTID(lidv) LEVEL(MYTEST)"
"LMDLIST LISTID("lidv") OPTION(list) dataset(dsvar) stats(yes)"
do while rc = 0
/* Delete or whatever */
end
"LMDFREE LISTID("lidv")"
For all these methods you need to fully qualify the first High level qualifier.
Learning what Rexx / ISPF will serve you into the future. In the ISPF Editor, you can use the model command to get Templates / information for all the ISPF commands:
Command ====> Model LMDINIT
will add a template for the lmdinit command. There are templates for rexx, cobol, pl1, ISPF-panels, ISPF-skeletons messages etc.
Thanks Bruce for the comprehensive answer. According to Bruce's tips, I just worked out a one-line Shell command as below:
tsocmd "listcat lvl(MYTEST) " | grep -E "MYTEST(\..+)+" | cut -d' ' -f3 | xargs -I '{}' tsocmd "delete '{}'"
Above command works perfectly.
Update - The IDCAMS DELETE command has had the MASK operand for a while. You use it like:
DELETE 'MYTEST.**' MASK
Documentation for z/OS 2.1 is here.

How to remove an entry from the history in ZSH

Let's say I ran a command using a zsh
echo "mysecret" > file
I can easily print the history including the entry numbers using the command fc -l:
1 echo "mysecret" >| file
But how can I easily delete an entry from the history?
I cannot find a corresponding paragraph in man zshbuiltins.
*BSD/Darwin (macOS):
LC_ALL=C sed -i '' '/porn/d' $HISTFILE
Linux (GNU sed):
LC_ALL=C sed -i '/porn/d' $HISTFILE
This will remove all lines matching "porn" from your $HISTFILE.
With setopt HIST_IGNORE_SPACE, you can prepend the above command with a space character to prevent it from being written to $HISTFILE.
As Tim pointed out in his comment below, the prefix LC_ALL=C prevents 'illegal byte sequence' failure.
I don't know if there is some elegant method for doing this, but in similar situations I have logged out (allowing zsh to empty its buffer and write my history to file), then logged in, and finally manually edited ~/.zsh_history, deleting the "dangerous" line.
If you use the HIST_IGNORE_SPACE option in zsh you can prepend commands with a space " " and they will not be remembered in the history file. If you have secret commands you commonly use you can do something along the lines of: alias hiddencommand=' hiddencommand'.
If you only want to make an occasional deletion, I think that it's easier to manually edit your .zsh_history.
In a zsh terminal:
Close the terminal session with the command to delete.
open a new session,
open ~/.zsh_history with a text editor (pico, Emacs, vim...),
delete the faulty lines,
close the editor, close the terminal session and open a new one,
enter history and the unwanted history item will be gone.
(Make sure the editor hasn't backed up the previous .zsh_history instance.)
(Solution based on https://til.hashrocket.com/posts/zn87awopb4-delete-a-command-from-zsh-history-)
This function will remove any one line you want from your Zsh history, no questions asked:
# Accepts one history line number as argument.
# Use `dc -1` to remove the last line.
dc () {
# Prevent the specified history line from being
# saved.
local HISTORY_IGNORE="${(b)$(fc -ln $1 $1)}"
# Write out the history to file, excluding lines that
# match `$HISTORY_IGNORE`.
fc -W
# Dispose of the current history and read the new
# history from file.
fc -p $HISTFILE $HISTSIZE $SAVEHIST
# TA-DA!
print "Deleted '$HISTORY_IGNORE' from history."
}
If you want to additionally prevent all dc commands from being written to history, add the following in your ~/.zshrc file:
zshaddhistory() {
[[ $1 != 'dc '* ]]
}
Update
I've now published a more comprehensive solution as a plugin: https://github.com/marlonrichert/zsh-hist
tldr:
vi $HISTFILE
more details:
run vi $HISTFILE
SHIFT + g — to go to the end
dd — to remove line
:wq — to save and exit
reload session or open a new tab to see changes
remove your line
In BASH [Not ZSH]:
1- in bash terminal type
hsitory # This will list all commands in history .bash_history file with line numbers
ex:
...
987 cd
988 ssh x#127.0.0.1
990 exit
991 cd
2- pick the CMD line number you want to delete
history -d 988
Note: if you want to delete for example last 3 CMDs, just pick the third line number from bottom ex: 988 and repeat the CMD history -d 988 3 times in sequence.
Source

How to make a line as a comment in SED

Excuse me if it is a repeat. I have crontab entries which look like:
* * * * * sleep 15;/etc/opt/wer.sh
1 * * * * /opt/sfm/qwe/as.sh
How to insert a # on the line which contains a call to "as.sh" using sed?
How to uncomment it back?
You can use:
sed '/\/as.sh/s/^/#/'
which will replace the start-line zero-width marker with a comment character for all lines containing /as.sh, as shown in the following example:
pax> echo '
* * * * * sleep 15;/etc/opt/wer.sh
1 * * * * /opt/sfm/qwe/as.sh
' | sed '/\/as.sh/s/^/#/'
* * * * * sleep 15;/etc/opt/wer.sh
#1 * * * * /opt/sfm/qwe/as.sh
But you need to keep in mind a couple of things.
It's usually not enough to just change the file, you also need to notify cron that it needs to re-read it. This is automatic if you use the crontab command itself but you may have to send a signal to cron if you're editing the file directly.
It's not always a good idea to turn scripts loose on important system files. Make sure you know what you're doing and don't trust any old codger on the net (including me). Test it thoroughly.
To get rid of the marker, use:
sed '/\/as.sh/s/^#//'
This is the opposite operation, it finds those lines containing /as.sh and substitute any # character at the start of the line with nothing.
To add the comment:
sed -e "s/\(.*\)\(as.sh\)/\#\1\2/g"
To remove the comment:
sed -e "s/\(^#\)\(.*\)\(as.sh\)/\2\3/g"
use crontab -e to modify the current user's crontab.

Cron fails on single apostrophe

The following does work as expected:
date +'%d-%b-%Y-%H-%M'
28-Sep-2009-14-28
But none of the following 4 entries from crontab are working.
* * * * * date +\'%d-%b-%Y-%H-%M\' >> /backup/shantanu/testing.txt
* * * * * date +'%d-%b-%Y-%H-%M' >> /backup/shantanu/testing1.txt
* * * * * date +"%d-%b-%Y-%H-%M" >> /backup/shantanu/testing2.txt
* * * * * date +\"%d-%b-%Y-%H-%M\" >> /backup/shantanu/testing3.txt
Error:
/bin/sh: -c: line 0: unexpected EOF while looking for matching `"'
/bin/sh: -c: line 1: syntax error: unexpected end of file
I can save the same code in a shell script and set the cron, but I will like to know if it is possible to directly set a cron for the task.
The actual cron entry that I am trying to set looks something like this...
16 * * * * mysqldump myDB myTB > /backup/ABCbc$(date +'%d-%b-%Y-%H-%M').sql 2> /backup/ABCbc_errORS$(date +'%d-%b-%Y-%H-%M').txt
There are four common causes for cron job commands to behave differently compared to commands typed directly into an interactive shell:
Cron provides a limited environment, e.g., a minimal $PATH, and other expected variables missing.
Cron invokes /bin/sh by default, whereas you may be using some other shell interactively.
Cron treats the % character specially (it is turned into a newline in the command).
The command may behave differently because it doesn't have a terminal available.
You must precede all % characters with a \ in a crontab file, which tells cron to just put a % in the command, e.g.
16 * * * * mysqldump myDB myTB > "/backup/ABCbc$(date +'\%d-\%b-\%Y-\%H-\%M').sql" 2> "/backup/ABCbc_errORS$(date +'\%d-\%b-\%Y-\%H-\%M').txt"
(As a separate matter, always put double quotes around a "$variable_substitution" or a "$(command substitution)", unless you know why not do it in a particular case. Otherwise, if the variable contents or command output contains whitespace or ?*\[, they will be interpreted by the shell.)
As long as there are no spaces in the format string supplied as an argument to date, you should not need the ticks at all.
date +%d-%b-%Y-%H-%M
should work.
You're using a syntax not supported by /bin/sh. Try invoking your preferred shell and passing the command as an argument.

Resources