Need a non-binary alternative to the "test" command
Hi everyone!
I am currently in the very very early stages of learning how to use the bash shell as well as how to make scripts for it. Now I have a folder with pictures in it.. They are named chronologically in the following order: YYYYMMDD, for example 20090101 is January 1st, 2009. I am writing a small script which I want to do the following: 1. Check if there are any files from January 2. If there are, make a new directory called "January" and move them in there. Now this is a very simple script, and this is what I got for now: Code:
#! /bin/bash There is a problem with this script, though: The "test" command (the []) can only evaluate true/false statements and then exit with a 0 or a 1, accordingly. If I have several files from January 2009, it does not know which one to look at, and it exits with the error: Code:
/path/to/the/script/script.bash: line 6: [: path/to/my/pictures/20090101: binary operator expected Best regards, ~UNGR P.S. I realize my writing may be a little confusing, since I am still learning this and don't fully understand it all. If you need any clarifications, please don't hesitate to ask. I welcome all help! P.P.S. I have used these forums quite a bit, but this is my very first question. You all seem like a bunch of great guys, and I'm looking forward to ruthlessly leech on your knowledge! :) |
It seems you've read up quite a few things about the if test in bash. So I'm going to give you a slightly advanced answer.
So if only looks at the exit status of the test program ([ is simply an alias for test, as you probably knew already). As you probably already know, other programs also have exit statuses. if can use these the same way it uses the exit status of test. The real problem you are facing, is that test now gets fed a commandline like this: Code:
test -e path/to/my/pictures/20090101 path/to/my/pictures/20090102 path/to/my/pictures/20090103 path/to/my/pictures/20090114 An operator that can handle 2 arguments is a binary operator, binary refers to "has 2 sides", not "is made up of 1s an 0s". Now the problem is understood, the solution. ls is a command that can accept multiple filenames. If it cannot find any files, it exits with exit status 2, if it can it exits with exit status 0. So if can be used together with ls to find out if there is any number of files with that name-pattern. so this should work: Code:
if ls path/to/my/pictures/200901* Also, this is quite unreadable for people who aren't used to using if this way. Using $?, the variable with the last command's exit status, is more common. This suppresses the output of ls and uses $?: Code:
ls dinge > /dev/null 2>&1 |
Thank you VERY much for your answer - very quick and very detailed!
Now I understood why it would suppress the output of ls to send it to the /dev/null, but what is the "dinge" in line 1 of your solution (seen below)? This is probably incredibly basic, but the guide/tutorial I followed did not cover this. Quote:
|
oops...
"dinge" is a Dutch dialect word for "stuff" I use it a lot for temporary files and testing commands. You should substitute it for your file name pattern, like: Code:
ls path/to/my/pictures/200901* > /dev/null 2>&1 |
Quote:
Also, I have a single last question: The "2>&1" - what exactly does this do? My guide used ">&2" and said it was something about redirecting to Standard Error... Would you care to elaborate on this? And bear in mind, I started learning this about four days ago, so please go real slow on me! Thanks again for your time - it is VERY much appreciated! |
2>&1 redirects the output that the program sends to Standard Error to Standard Output
>&2 redirects the output that the program sends to Standard Output to Standard Error Standard Output, Input and Error explanation: http://en.wikipedia.org/wiki/Standard_streams redirection explanation: http://en.wikipedia.org/wiki/Redirection_(computing) guide with an even better explanation of these (and more): http://tldp.org/HOWTO/pdf/Bash-Prog-Intro-HOWTO.pdf Most programs send their output to stdout. If an error occurs, like "file not found" they send an error message to stderr. If you are simply typing in a command on the terminal, both stdout and stderr outputs are simply shown on the screen. If you want to save the output of a command to a file, you can do that with a command like "ls -l > file" But you probably don't want ugly error messages mixed with your pretty program output. That's why output and error are on a separate "channel". But sometimes you do want this. That's why the 2>&1 and the other exist. I simply put both in /dev/null. Your guide preserved both on stderr, as a sort of debugging output. PS: If you didn't already, check out some of the howtos on The Linux Documentation Project (where the Bash Programming Howto came form). PPS: there seems to be a convention to welcome people to LQ when responding to their first post. I always forget to do that: Hi, welcome to LinuxQuestions.org! Enjoy your stay on these forums. |
Quote:
|
Quote:
|
All times are GMT -5. The time now is 07:35 AM. |