98

Well, I'm a linux newbie, and I'm having an issue with a simple bash script.

I've got a program that adds to a log file while it's running. Over time that log file gets huge. I'd like to create a startup script which will rename and move the log file before each run, effectively creating separate log files for each run of the program. Here's what I've got so far:

pastebin

DATE=$(date +"%Y%m%d%H%M")
mv server.log logs/$DATE.log
echo program

When run, I see this:

: command not found
program

When I cd to the logs directory and run dir, I see this:

201111211437\r.log\r

What's going on? I'm assuming there's some syntax issue I'm missing, but I can't seem to figure it out.


UPDATE: Thanks to shellter's comment below, I've found the problem to be due to the fact that I'm editing the .sh file in Notepad++ in windows, and then sending via ftp to the server, where I run the file via ssh. After running dos2unix on the file, it works.

New question: How can I save the file correctly in the first place, to avoid having to perform this fix every time I resend the file?

Cat5InTheCradle
  • 1,103
  • 1
  • 8
  • 7
  • 2
    `\r` is carriage_return, examine your bash script, maybe is included inside the script – ajreal Nov 22 '11 at 14:07
  • Where would that carriage return be coming from? I'm guessing that something about `logs/$DATE.log` is wrong, but typing `echo logs/$DATE.log` outputs the correct path. – Cat5InTheCradle Nov 22 '11 at 14:12
  • how would i know? please attach the corresponded bash script, likely there is unnoticeable whitepspaces – ajreal Nov 22 '11 at 14:16
  • Added a pastebin link to the main post, but that code snippet is literally the entire script, I've just substituted 'echo program' for the line that launches a java .jar – Cat5InTheCradle Nov 22 '11 at 14:19
  • no idea ... seems to be correct, how about you try to append some strings after the `DATE=$(date +"%Y%m%d%H%M")`? – ajreal Nov 22 '11 at 14:28
  • turn on shell debugging with `set -vx` just above your DATE=... cmd. Then you can see how variables are being expanded. If you're editing this file on Windows and then using the editor's ftp client to return the script to your unix/Linux environment, then you likely are getting DOS line-endings added to your script, i.e CR/LF. For *nix, you only want the LF. See if you can turn it off in your editor's setup. `dos2unix filename` on your *nix side will also fix this issue. Good luck. – shellter Nov 22 '11 at 14:37
  • I am using Windows to create the file, using Notepad++ then sending via FTP to the server and running via Putty SSH. – Cat5InTheCradle Nov 22 '11 at 14:54
  • @AgentSnazz - When you use Notepad++, you need to set the line endings to Unix line endings. Select the menu _Edit->EOL Conversion->Unix Format_ when you edit a shell script. You can also look under _Settings->Preferences_ menu item. Under the _New Document/Default Directory_ tab. This will allow you to make sure all new files have Unix line endings. – David W. Nov 22 '11 at 20:28
  • Possible duplicate of [Append date to filename in linux](https://stackoverflow.com/q/1795678/608639), [Appending a current date from a variable to a filename](https://unix.stackexchange.com/q/57590), [Adding timestamp to a filename with mv in BASH](https://stackoverflow.com/q/8228047/608639), etc. – jww Oct 15 '19 at 08:24

9 Answers9

107
mv server.log logs/$(date -d "today" +"%Y%m%d%H%M").log
dqw
  • 1,189
  • 2
  • 6
  • 5
  • 21
    `date +"%Y%m%d%H%M"` if your bash is a bit different – zinking Sep 11 '14 at 07:20
  • 6
    To stress @zinking's point, there must **not** be a space between the plus sign and the double quotes – puk Aug 10 '17 at 02:11
  • 3
    I use `date +"%Y-%m-%dT%H:%M:%S"` for a readable timestamp with seconds; it works fine on Linux with its colons in filenames. – Asclepius Nov 20 '21 at 18:38
24

The few lines you posted from your script look okay to me. It's probably something a bit deeper.

You need to find which line is giving you this error. Add set -xv to the top of your script. This will print out the line number and the command that's being executed to STDERR. This will help you identify where in your script you're getting this particular error.

BTW, do you have a shebang at the top of your script? When I see something like this, I normally expect its an issue with the Shebang. For example, if you had #! /bin/bash on top, but your bash interpreter is located in /usr/bin/bash, you'll see this error.

EDIT

New question: How can I save the file correctly in the first place, to avoid having to perform this fix every time I resend the file?

Two ways:

  1. Select the Edit->EOL Conversion->Unix Format menu item when you edit a file. Once it has the correct line endings, Notepad++ will keep them.
  2. To make sure all new files have the correct line endings, go to the Settings->Preferences menu item, and pull up the Preferences dialog box. Select the New Document/Default Directory tab. Under New Document and Format, select the Unix radio button. Click the Close button.
Community
  • 1
  • 1
David W.
  • 105,218
  • 39
  • 216
  • 337
  • I'll see if I can try that. Running dos2unix once the file is ftp'd to my linux server solves the problem, but I'm looking for a way around that extra step. I don't have a shebang at the beginning, that may be the key. – Cat5InTheCradle Nov 22 '11 at 16:08
  • 2
    @AgentSnazz - Ah ha! That's the problem. Unix shell scripts must have Unix line endings. Windows/MS-DOS uses carriage return-linefeed (aka CRLF or \r\n) to mark the end of the line. Unix uses just a linefeed (aka LF or \n). If you are editing a file for Unix on a Windows machine, you must use a program editor that can do the correct line endings (like [Vim](http://www.vim.org) or [Notepad++](http://notepad-plus-plus.org/). **Do not ever use Notepad**. That's why you're seeing the `\r` in the file name. There's an invisible `\r` at the end of each line in your program. – David W. Nov 22 '11 at 20:06
11

A single line method within bash works like this.

[some out put] >$(date "+%Y.%m.%d-%H.%M.%S").ver

will create a file with a timestamp name with ver extension. A working file listing snap shot to a date stamp file name as follows can show it working.

find . -type f -exec ls -la {} \; | cut -d ' ' -f 6- >$(date "+%Y.%m.%d-%H.%M.%S").ver

Of course

cat somefile.log > $(date "+%Y.%m.%d-%H.%M.%S").ver

or even simpler

ls > $(date "+%Y.%m.%d-%H.%M.%S").ver

Cyberience
  • 972
  • 10
  • 15
9

I use this command for simple rotate a file:

mv output.log `date +%F`-output.log

In local folder I have 2019-09-25-output.log

alfiogang
  • 435
  • 5
  • 7
5

First, thanks for the answers above! They lead to my solution.

I added this alias to my .bashrc file:

alias now='date +%Y-%m-%d-%H.%M.%S'

Now when I want to put a time stamp on a file such as a build log I can do this:

mvn clean install | tee build-$(now).log

and I get a file name like:

build-2021-02-04-03.12.12.log

cptully
  • 615
  • 1
  • 9
  • 24
5

Well, it's not a direct answer to your question, but there's a tool in GNU/Linux whose job is to rotate log files on regular basis, keeping old ones zipped up to a certain limit. It's logrotate

Didier Trosset
  • 36,376
  • 13
  • 83
  • 122
1

You can write your scripts in notepad but just make sure you convert them using this -> $ sed -i 's/\r$//' yourscripthere

I use it all they time when I'm working in cygwin and it works. Hope this helps

mkrouse
  • 277
  • 2
  • 4
  • 11
0
$mv OldFileName NewFileName$(date +%Y%m%d%H%M%S)
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
0

just use lowercase (for YEAR-month-day) and UPPERCASE (for HOUR-MINUTE-SECOND) like

TIMESTAMP=$(date +"%**Y**.%m.%d-%H.%M.%S") get **2023**.04.13-07.56.05

or

TIMESTAMP=$(date +"%**y**.%m.%d-%H.%M.%S") get **23**.04.13-08.01.03
Rohit Gupta
  • 4,022
  • 20
  • 31
  • 41