- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Admin
That idiom is actually a feature because shell redirection retains owner, group and permissions of the target file in case it already exists. And I'd wager that it's POSIX sh compatible that way and not bash-specific. I didn't look it up, though.
Admin
is this 8bit-safe? my hunch is, do this with a binary file and you have garbage
Admin
More Free Software hate as usual from the committed MS shill (you've been at it for years and it's very obvious, I see you), and nice work approving the FUD comment above before any of the others.
Admin
Just wanted to apologise for my previous comment - some people bat for MS because of EEE-induced brain damage, not out of malice or lack of principles, and it was unfair to attribute your long history of vague and unfounded doubt-sowing (and equally vapid MS boosterism) to the latter and not the former.
Admin
What happens if myDestFile already exists? If I'm not mistaken this code will append the data of mySourceFile at the end.
In extremely narrow situations I can see that as the intended result (if both are TXT, for example) but if there is any other data in either this will just leave the user with a junk file that can't be used by anything.
Admin
If the output of
cat
isn't"Meow"
, then it shouldn't be used.Admin
No, it's fine (easy to test, compare a hash of /bin/cat against a version of the file you created using this cat-copy method).
Admin
It's more accurate to say that there are objects in the file system for which it will break, almost exclusively things that aren't really files (listening UNIX sockets, device files, etc.).
cp
won't necessarily do something intelligent with them, but whatever it does will be less stupid than what cat-greater will do.Admin
I can't wait to see the result when a link to /dev/zero is in the directory that is processed.
Admin
It will also break if there is any metadata that cp would copy and which the default for new files in that location is not the same.
Symbolic links, perhaps. xattrs. Permissions. The assumption that a filesystem is a strict tree whose interior nodes are a map of string to node, and leaves are byte arrays, is weirdly common considering how few OSes it's true for.
Admin
Is this some kind of new trolling routine? Am I out of the loop?
Admin
No, the > operator will overwrite the destination file. If you want to concatenate the output of the cat command to the end of the file, you'd need to use the >> operator. The cat command itself only concatenates the list of files it's passed into a single output stream.
Admin
As someone who loves linux, bash is awful. You can learn to use it, and you can even be competent in it, but it's a badly designed mess.
Of course, microsofts old equivalent (cmd) is even worse, though at least powershell seems to be well designed, even if it's overly verbose and annoying to use. There might be other better linux shells (zsh for example), but AFAIK they are all "bash-ish" in style and no easier to write scripts for.
I'd rather write a python script than go anywhere near a shell scripting language.
Admin
That used to be true for Python, but the 2/3 conversion broke that for a number of years: you couldn't guarantee Python was installed in the first place, but now you couldn't guarantee which Python was installed. Bash has its warts, but I still prefer it for anything at a relatively low level of complexity. If I'm reaching for Python, it's because I have a high degree of control over the target environment and can control what is installed there and am doing a task that's fairly complicated (100+ line script).
Powershell is nice in concept, but the ergonomics are awful, and I'm actually not entirely sold on passing objects between processes. Passing text streams might be a very 1970 way of sharing data, but it's a very flexible way of sharing data. If only we had a better tool that AWK for splitting those streams up. It's… awkward.
Admin
Good points. I hadn't thought about symlinks (which will become normal files in the output), and of course the permissions, even on ordinary files, won't be copied (the destinations will universally have whatever permissions your UMASK puts on there, often stuff like 660/rw-rw----).
Such a shame there's no POSIX equivalent of CopyFileExW().
Admin
cp filename filename
will complain, where
cat filename >filename
leaves you with an empty file.
Admin
A very handy feature -
cat /dev/null > /var/log/unruly_file.log
is a great way of truncating large log files without messing with the original file permissionsAdmin
Out of curiosity: Could you elaborate on why you think bash is a "a badly designed mess"?
I'm with Remy here - due to the python 2/3 snafu and installed-python-version roulette (coupled with inconsistent system-package handling), I'd rather pick bash for simpler tasks rather than reaching for python, especially for scripts which need to run on other machines.
If I need to do this in python - especially for scripts which need non-default libs - I would have to define a virtual environment (first hoping that the python version of choice is installed on the system) and then a
requirements.txt
to make sure that all deps are present.Easier to just have a bash script (or even sh) which would work on multiple systems
Admin
If the destination file already exists, a single greater-than symbol means to replace the contents; two greater-than symbols would mean to append.
Admin
Believe it or not, just
> /var/log/unruly_file.log
will do the same thing. It's kind of cute, but it's too confusing and non-obvious for me to advocate using it. But I do grudgingly admire it when I've seen others use it.
Admin
Yes, bash has maximum portability, and I've written 250+ line bash scripts when that was required, but hated it.
Bash is bad because
if
statements are complicated. [ vs [[, "=" is regexp, not equality, handling of empty strings, which regexp conventions does command X use, etc.Bash is great at starting other processes and dealing with steams of date.
My smart-ass line is "the most important thing to know about bash is when to stop using it". Because my fallback language is Perl, not Python, the 10+ year old version that is almost certainly installed will let do all the munging I want (though using external programs is harder, but
sed
,awk
,grep
, etc. have lovely equivalents within Perl.)Admin
There are some surprising variations among installed Bash versions too, such as whether particular commands create subshells. That said, it is decent for the tasks it was designed for, which are much smaller than the range of problems that exist in the presence of GUIs and web sites.
Oh, and "commenter", take a chill pill. Everyone was not put on earth to kiss RMS's foot (yuck).
Admin
Another reason Perl was an early easy-sell as well. No more worries about whitespace and multiple quotes-within-quotes-within-quotes. And no forking for common operations.
Admin
cat mySourceFile > myDestFile
will give an error ifmyDestFile
exists and is a directory, wherecp mySourceFile myDestFile
will copy the file to a file namedmySourceFile
insidemyDestFile
.I sometimes use
cat mySourceFile > myDestFile
if I don't want any file permissions to be copied and am too lazy to remember which option to give tocp
to prevent that.Admin
For thosae who post about permissions and the like (including "non-file" entries.... perhaps the behavior of "cat>file" is actually the desired one? Of course since there are no comments or documentation posted, one can not tell [oh yea, the documentation is on a coffee stained piece of paper in Sid's bottom filling cabinet, but it is locked, and Sid had the key when he left the company 10 yeas ago --- but it IS documented.....
Admin
Yeah, bash's string handling does suck sweaty donkey balls - even with pipes to other utilities :D
If there's a lot of string manipulation involved, I definitely reach for some tool other than bash.
Admin
Bonus points for copying a video file by re-encoding it into the same format and resolution. Ditto for audio files.
Admin
Today's article illustrates the main difficulty of doing anything with Bash or any other Unix shell: a shell doesn't "do anything"; it orchestrates other programs that do it. So your proficiency as a shell script author will depend on knowing the ins and outs (literally) of a couple dozen other programs. I acquired that knowledge by being in the right place at the right time. Recently I wanted to present an introduction to shell scripting, so I looked all over for a single list of the common scripting commands — not the common interactive commands! — and came up short. So one should not be surprised to find shell scripts doing things in various forced ways.
Admin
You unmitigated monster! I like you.
Admin
For truncating a file , you can also use
:> /var/log/somefile
and I think that when using cp with an existing destination, will unlink the destination file and create a new inode for it while redirection will truncate the destination file and append the rest. Which is relevant if the file is large and still open by some process, as the old file will need disk space even though it is already unlinked.
Admin
"Passing text streams might be a very 1970 way of sharing data, but it's a very flexible way of sharing data."
But passing objects is even more flexible. With text, it's just text. With objects, you can have more data types (no more stringly typed data). With text, you have to know how to parse it. With objects, you get fields that you can inspect and get exactly what you want.
PowerShell makes it easy to format data when it's printed to the console in a way that would be very hard with text. If you want to print a list with columns that is truncated at the console width (i.e. don't assume 80 characters) then to do so with text would require each program know how wide the console is and have it's own formatting code. Kinda breaks the "do one thing well" that Linux/Unix is known for.
Admin
What about the obvious way: "dd if=${INFILE} of=${OUTFILE} iflag=direct oflag=direct bs=1 speed=1" - because we want a byte-wise exact copy? There's plenty of potential for optimization hidden in the speed= parameter (use for promotion)!
Admin
This WTF post was amusing. However the comment section is amazing. Apparently that one post is pushing buttons for a lot of folks -- those who need to troll, those who know how a un*x system works, and those who clearly don't but still boast their incorrect assumptions without apparently even bothering to $ man bash first.
I love to RTFM the bash man page. After 2 decades of using and abusing bash, I still need to read it from time to time to remember some obscure syntax, and learn yet another little detail I had missed all along in the process.
Admin
On the other hand, passing around streams of bytes is more universal. Any file can be seen as a sequence of bytes, even before an interpretation was associated with it. It is also a concept, that is unlikely to ever change, so in a sense it is infinitely forward-compatible. It is also more portable, because any system will usually be able to process streams of bytes, since they are the lowest-level representation of data.
That said, if there were a defacto-default object-oriented shell for Linux, it would make me happy. Python is great for scripting, definitely much easier to debug especially, but for most output data, passing it around as "tables" would indeed be more useful.
But then the program code would suddenly be specific to shells of that system, instead of being portable across different operating systems... So in order to really be better than "stream of bytes" output, the shell would also need to be available on all operating systems.
In that sense I somehow feel, that "stream of bytes" fits open source utilities better than object oriented variants. Produce output that can be consumed by human interactors on any system, leave interpretation of the data to the people building automations around it, and find conventions for representing structured data in an both easily parsed and manner that is also well formatted for human consumption. That latter part is probably currently not quite there, though most programs where it actually is relevant already provide an easily processed tabular output format – what's missing is a clear standardization for the handling of values represented by strings with whitespace, and for accessing table columns by unique, LANG-independent names instead of column number.
Admin
@R3D3: I know, I know!!
Let's all use JSON & Javascript. That's the universal text format for data and the universal shell scripting language.
Yes, I'm kidding.
Ultimately your argument, which Im not entirely unsympathetic to, is that the lowest common denominator is best because it's the most common. I prefer to focus more on the "lowest", and try to avoid using "lowest" [whatever] when a higher [whatever] is available.
How many of us truly are writing code for an infrastructure with no configuration control, an unbounded list of OSes & versions and shells and ... to be compatible with, etc.? Certain public library authors sure are. At my shop we've got a rather more limited array of environments to keep compatibility with.
Admin
I'll say! There's no use of Excel anywhere I can see.
Admin
In the same comment that you supposedly apologize, you go on to say that anybody who likes working with Microsoft tech must be brainwashed? Sounds like "sorry, but not sorry" to me.
You're either trolling, or you're a blind devotee to certain misguided (some of which are outdated) views and beliefs. You come across as someone who puts opinion above pragmatism and if I were you I would take a long hard think about how that might affect how other people view you in a professional capacity.
Admin
The difficulty with an OO shell is when command A outputs object type X and command B expects object type Y. The in-between manipulation can be just as hard if not harder than text stream munging.
That said Bash and PowerShell both work well enough and I can muddle my way through tasks with either one.
Admin
So it's a copycat?
Damn, it was right there all along...
Admin
yeah, but you get used to it, like with any other clunky feature of any other language
I think a PITA is a bit extreme, I've been writing "spaces in filenames" compliant shell script for over 15 years now but I'm not a programmer/developer, I'm a sysadmin so maybe it's just getting used to the tools you have
I'm with you though in that if you're gonna replace bash for your scripting needs, perl might be your best choice for many reasons (even if I don't particularly like perl myself)
Admin
There’s also a time to stop using Perl, and it’s “years ago.”
“Please give me $$_[$#]->{query}. I want to s:%(\x\x):chr(hex $1):ge it.” Statements dreamed up by the utterly Deranged
Admin
Firstly, that Perl code that you posted isn't even valid; for starters, \x\x is wrong and will not parse.
Second, Perl code can be be written to be quite readable:
Perl can be written very elegantly if one cares to do so, same as with any language. Anyone can criticize a lang that they do know or do not know well. Your post frankly borders on disinformation.
Admin
The point was probably more about Perls somewhat hard-to-remember syntax. Same as I can never remember, which is the correct idiom for stripping the extension from a filename in Bash, that's definitely easier in Perl (mostly because regexps use at least similar syntax across various languages), before even accounting for appropriate utility functions, that do exist.
Perl 5 has its fair share of annoyances, but it makes a powerful, probably-everywhere-available scripting language, with an easy mechanism for ensuring that a minimal version is installed, and at the same time ensuring that your code does not use features that require a higher version.
Also, I just learned that Perl 6 is called "Raku" since a few years. I vaguely remember "Rakudo" as the main implementation, but I never realized, that the language itself had been renamed.
Admin
Your hunch would be wrong.
cat
is 8-bit clean (on Unix systems). In fact it is the canonical way to reconstitute files that have previously been split into smaller parts.Admin
Wrote: but for most output data, passing it around as "tables" would indeed be more useful
Ah yes. Think of the IBM i.
The pipe operator is terrific: no need to think a filename and a place to put it, no need to delete that file when you are done. But it is wonderful to have a system which speaks "tables" natively.
Terry.