ChangeAgent wrote:
marshaul wrote:
OK, do a couple of things (these are all going to be commands in the Terminal).
ls -l /pathto/crontab
here is where I get stuck, this bit does not work.
I do however have a user cron tab, I can open it (crontab -l ) and read what is in it.
What happens? It's difficult for me to guess what may be wrong without the terminal output. "No such file or directory", possibly? Be sure to always share the input and output of terminal commands, otherwise folks will just be guessing.
Since my user crontab exist I thought I do part two of your suggestion.
However I do not understand this. If I have the text of my script in a text (.txt) document, how do I call it? is it executable?
I'm not sure I understand the question. I'll answer the best I can, and then I'll ask a question so I might be able to answer better.
On a unix-based operating systems, file extensions don't have any special power. Nothing prevents a process from treating the data in a file differently from how it was intended. For instance, remember I talked a bit about less, the command line pager tool? Well, less is intended to display the contents of files whose data are encoded text. But it will run the routine on files which aren't quite happily; it doesn't really know or care. If you run a command like "less /usr/bin/unzip" you'll see the text interpretation of the binary, which of course is basically unreadable garbage.
File extensions are little more than flags to hint to the operating system, and the user, what programs know how to deal with a certain file type. Some programs run checks to see if the extension of input files matches a list of useable extensions, but this is not strictly necessary. Others might treat a file differently, or do something different to it, depending on its extension; but again this is not necessary. Most of the time, you can change an extension to whatever you want and things will still work, especially in the command-line environment with command-line tools.
For instance, less, as I mentioned, doesn't really give a squat what the extension is; it can be anything, or nothing.
The command-line editor vi (or the more modern and popular vim, for vi iMproved) similarly will open, display, and allow editing of any file type, regardless of extension. What vim will do, however, is take a quick look at the file extension, and use that for syntax highling, say, if a programming language (C or whatever) code file is opened. That's basically all vim uses the file extension for: to add pretty colors to certain text combinations, depending upon the file extension.
And code files themselves are a great example of all this. With basically every language, routines are written into files which are the same as basic .txt files, but have the appropriate extension (.c or whatever), to identify them to the user, to editors like vi, and to compilers which are finicky enough to care. If you write a routine in C in a .txt file, and then change the extension to .c at the last minute, nothing else has changed; just that extension.
To sum all this up very succinctly: there is no inherent relationship between a file's contents and its extension. In many cases it's a good idea to establish and maintain such a relationship (by consisten use of extensions), but it's not inherent. A file is just a bunch of data, and the extension is just part of the name of the file, and neither directly affects the other.
By convention, binary executables on a unix-based system don't have any extension at all.
(Consider the Mac's .app extension, which is a signifier to the OS that the directory is an application. Within that directory tree – specifically at SomeApp.app/Contents/MacOS/ – will be found binary executables (without extensions!), which are the files actually executed by the OS to make it all happen. Everything else is just data files like icons, settings, etc.)
Now, to get to the point: a shell script is just a text file. Consider the file "foo.txt", which contains exactly one line:
echo "Test!"
(The echo command merely sends its argument to STDOUT, which in the case of something run from the command line, is merely the terminal window itself. So this just prints "Test!" in the terminal window.)
There are actually two ways the OS might know that it's a script, either one of which is enough to make it run the script (both are only used so as to avoid a script suddenly not working when it's called differently), and neither one of which is the extension.
For instance, if I run
sh foo.txt
The script works (I see "Test!" in the terminal).
Now, I might rename it "foo.sh" to remind me that it's a shell script. (Or I might rename it foo.zsh because I use z-shell (zsh) and write a lot of my scripts using its syntax rather than the traditional .sh shell syntax.)
Or, I might not. I might simply rename it "foo", and eliminate the extension. This changes nothing.
Now, I might not want to have to type "sh" every time I wish to call my script. I might wish it instead to behave as though it were a binary executable, so I can merely type "/pathto/foo" rather than "sh /pathto/foo" to execute it, or just ./foo (Note: in a unix command line, the sequence ./ as a path means "here, in the present working directory (PWD)", which is why you might see me call a script using ./foo).
There is a bit of metadata (a permissions flag) which tells the OS that a given file is an executable, rather than a simple data file. (Actually, there are three of them, but you can google "unix permissions" if you want to read how that works.) Note that this bit is metadata; it is not stored as part of the file name or extension. To set the executable permission on a file, the command
chmod +x ~/foo
is used (on the Mac, ~ indicates the users home folder, so using ~ in a path is the same as typing /Users/yourusername). Now I can simply run "./foo" to execute my script.
Only problem is, that is only guaranteed to work from within a shell (terminal) environment which understands .sh script syntax. All we've done is tell the OS that the file is executable. We haven't specified how, and it's not binary so it won't execute itself. A shell, like the sh shell or zsh, will look at the file and say "oh, well it's executable, but it's not binary, so it must be a script", so it will begin running the commands in sequence, one line at a time, as though there were simply typed into the terminal.
Now, if the process which attempts to execute the script isn't sh (or an sh-compatible shell like zsh), it might not know how to "execute" a bunch of lines of text (it doesn't know how to interpret those instructions as instructions). To rectify this, the hash-bang (or "shebang) line is used: the first line of the shell script is set to
#!/bin/sh
or
#!/bin/zsh
or
#!/pathto/whatever_shell_i_want_to_use
Now, on a unix-based system, this should be enough to get any dumb enviroment run the script: it looks at the file, sees the hash-bang, and knows it has to start up sh (or whatever) to interpret the script and carry out its instructions.
Notice that at no point in any of that did the extension actually matter at all. I could have left it as ".txt" and nothing would have changed.
(Incidentally, I hope you aren't actually copying and pasting the contents of the script into your terminal window! 😝 Use the cd (change directory) command to get into the directory where the script is – use tab completion to make that easier – and then type ./yourscriptname to execute it. Then, to repeat, simply press the up arrow followed by return. You can browse through the list of previously typed commands by pressing the up arrow repeatedly. Like I said, you should never do anything twice that you can make your computer do!)
I hope that helped. Now, for my question(s):
What is your script called? Where is it? Is it executable (ls -l will tell you this)? And, finally, what are the contents of your crontab file?