I am trying to write my first perl "hello world" program on Mac OS X Yosemite and it shows this error when I try to run this using terminal:
Unrecognized character \xE2; marked by <-- HERE after
print <-- HERE
near column 7 at test.pl line 4.
I couldn't figure out what was wrong in this program. Please help me out here.
Code:
#!/usr/bin/perl
use strict;
use warnings;
print “Hello world”;
Change the “” character in the print statement to "
Example
print "Hello world";
Make sure syntax like this ' should be proper. Check your perl file for syntax errors
perl -c testfile.pl
While it is not directly connected to this case, there's also a different situation when \xE2 error can appear, which can seem not obvious. One can also have a zero-width space in their string, which can also raise this error.
I couldn't see this character in notepad or notepad++, but I could see it in vim as <200b>. This character can be placed next to { and } characters when copying stuff from for example Microsoft Teams.
This link appears as the first one when searching for this kind of problem, so I thought it might be a good idea to post the solution here.
Related
I have recently started studying shell script and I'd like to be able to comment out a set of lines in a shell script. I mean like it is in case of C/Java :
/* comment1
comment2
comment3
*/`
How could I do that?
Use : ' to open and ' to close.
For example:
: '
This is a
very neat comment
in bash
'
Multiline comment in bash
: <<'END_COMMENT'
This is a heredoc (<<) redirected to a NOP command (:).
The single quotes around END_COMMENT are important,
because it disables variable resolving and command resolving
within these lines. Without the single-quotes around END_COMMENT,
the following two $() `` commands would get executed:
$(gibberish command)
`rm -fr mydir`
comment1
comment2
comment3
END_COMMENT
Note: I updated this answer based on comments and other answers, so comments prior to May 22nd 2020 may no longer apply. Also I noticed today that some IDE's like VS Code and PyCharm do not recognize a HEREDOC marker that contains spaces, whereas bash has no problem with it, so I'm updating this answer again.
Bash does not provide a builtin syntax for multi-line comment but there are hacks using existing bash syntax that "happen to work now".
Personally I think the simplest (ie least noisy, least weird, easiest to type, most explicit) is to use a quoted HEREDOC, but make it obvious what you are doing, and use the same HEREDOC marker everywhere:
<<'###BLOCK-COMMENT'
line 1
line 2
line 3
line 4
###BLOCK-COMMENT
Single-quoting the HEREDOC marker avoids some shell parsing side-effects, such as weird subsitutions that would cause crash or output, and even parsing of the marker itself. So the single-quotes give you more freedom on the open-close comment marker.
For example the following uses a triple hash which kind of suggests multi-line comment in bash. This would crash the script if the single quotes were absent. Even if you remove ###, the FOO{} would crash the script (or cause bad substitution to be printed if no set -e) if it weren't for the single quotes:
set -e
<<'###BLOCK-COMMENT'
something something ${FOO{}} something
more comment
###BLOCK-COMMENT
ls
You could of course just use
set -e
<<'###'
something something ${FOO{}} something
more comment
###
ls
but the intent of this is definitely less clear to a reader unfamiliar with this trickery.
Note my original answer used '### BLOCK COMMENT', which is fine if you use vanilla vi/vim but today I noticed that PyCharm and VS Code don't recognize the closing marker if it has spaces.
Nowadays any good editor allows you to press ctrl-/ or similar, to un/comment the selection. Everyone definitely understands this:
# something something ${FOO{}} something
# more comment
# yet another line of comment
although admittedly, this is not nearly as convenient as the block comment above if you want to re-fill your paragraphs.
There are surely other techniques, but there doesn't seem to be a "conventional" way to do it. It would be nice if ###> and ###< could be added to bash to indicate start and end of comment block, seems like it could be pretty straightforward.
After reading the other answers here I came up with the below, which IMHO makes it really clear it's a comment. Especially suitable for in-script usage info:
<< ////
Usage:
This script launches a spaceship to the moon. It's doing so by
leveraging the power of the Fifth Element, AKA Leeloo.
Will only work if you're Bruce Willis or a relative of Milla Jovovich.
////
As a programmer, the sequence of slashes immediately registers in my brain as a comment (even though slashes are normally used for line comments).
Of course, "////" is just a string; the number of slashes in the prefix and the suffix must be equal.
I tried the chosen answer, but found when I ran a shell script having it, the whole thing was getting printed to screen (similar to how jupyter notebooks print out everything in '''xx''' quotes) and there was an error message at end. It wasn't doing anything, but: scary. Then I realised while editing it that single-quotes can span multiple lines. So.. lets just assign the block to a variable.
x='
echo "these lines will all become comments."
echo "just make sure you don_t use single-quotes!"
ls -l
date
'
what's your opinion on this one?
function giveitauniquename()
{
so this is a comment
echo "there's no need to further escape apostrophes/etc if you are commenting your code this way"
the drawback is it will be stored in memory as a function as long as your script runs unless you explicitly unset it
only valid-ish bash allowed inside for instance these would not work without the "pound" signs:
1, for #((
2, this #wouldn't work either
function giveitadifferentuniquename()
{
echo nestable
}
}
Here's how I do multiline comments in bash.
This mechanism has two advantages that I appreciate. One is that comments can be nested. The other is that blocks can be enabled by simply commenting out the initiating line.
#!/bin/bash
# : <<'####.block.A'
echo "foo {" 1>&2
fn data1
echo "foo }" 1>&2
: <<'####.block.B'
fn data2 || exit
exit 1
####.block.B
echo "can't happen" 1>&2
####.block.A
In the example above the "B" block is commented out, but the parts of the "A" block that are not the "B" block are not commented out.
Running that example will produce this output:
foo {
./example: line 5: fn: command not found
foo }
can't happen
Simple solution, not much smart:
Temporarily block a part of a script:
if false; then
while you respect syntax a bit, please
do write here (almost) whatever you want.
but when you are
done # write
fi
A bit sophisticated version:
time_of_debug=false # Let's set this variable at the beginning of a script
if $time_of_debug; then # in a middle of the script
echo I keep this code aside until there is the time of debug!
fi
in plain bash
to comment out
a block of code
i do
:||{
block
of code
}
This is killing me. I have a config file, "myconfig.cfg", with the following content:
SOME_VAR=2
echo "I LOVE THIS"
Then I have a script that I'm trying to run, that sources the config file in order to use the settings in there as variables. I can print them out fine, but when I try to put one into a numeric variable for use in something like a "seq " command, I get this weird "invalid arithmetic operator" error.
Here's the script:
#!/bin/bash
source ./myconfig.cfg
echo "SOME_VAR=${SOME_VAR}"
let someVarNum=${SOME_VAR}
echo "someVarNum=${someVarNum}"
And here's the output:
I LOVE THIS
SOME_VAR=2
")syntax error: invalid arithmetic operator (error token is "
someVarNum=
I've tried countless things that theoretically shouldn't make a difference, and, surprise, they don't. I simply can't figure it out. If I simply take the line "SOME_VAR=2" and put it directly into the script, everything's fine. I'm guessing I'll have to read in the config file line by line, split the strings by "=", and find+create the variables I want to use manually.
The error is precisely as indicated in a comment by #TomFenech. The first line (and possibly all the lines) in myconfig.cfg is terminated with a Windows CR-LF line ending. Bash considers CR to be an ordinary character (not whitespace), so it will set SOME_VAR to the two character string 2CR. (CR is the character with hex code 0x0D. You could see that if you display the file with a hex-dumper: hd myconfig.cfg.)
The let command performs arithmetic on numbers. It also considers the CR to be an ordinary character, but it is neither a digit nor an operator so it complains. Unfortunately, it does not make any attempt to sanitize the display of the character in the error message, so the carriage return is displayed between the two " symbols. Consequently, the end of the error message overwrites the beginning.
Don't create Unix files with a Windows text editor. Or use a utility like dos2unix to fix them once you copy them to the Unix machine.
I'm working on windows and I want to find all the strings beetwen quotes, from a directory. For example, if I have this:
string s = "Hello World!"
The grep command should return me "Hello World!".
Here is how I do this:
grep -Roe \"[^\"]*\" directory
I need to redirect the output to a file but when I redirect the output, like this "grep -Roe \"[^\"]*\" directory > log" I get the following errors:
>: Invalid argument
log: No such file or directory
Do you know how can I solve this and redirect the output?
This is a very old question, and by now the OP has probably solved it... but for posterity, it's worth noting that the issue is to do with the compiler conventions (see this question, and find the answer headed "You aren't using a Unix shell. Quoting is different").
As you've discovered, while your expression will work fine at the command line, when it is used in conjunction with a redirect it gets parsed wrongly.
The solution is to escape the double quotes with a caret (^), not a backslash (\). And you need to escape the caret as well (with a caret). You should also enclose the entire search expression in single quotes.
Reformulating your command using caret-escaping (and enclosing in '') yields
grep -Roe '^"[^^^"]*^"' directory > log
I use this quite a bit to get style attributes from legacy HTML files (basically stuff written by a former coder who didn't believe much in separating content from presentation) - in which case I use
grep -iown 'style=^"[^^^"]*^"' index.html > styles.txt
It works like a charm.
Imagine a code repository where every in HTML file, even the p tags go something like <p style="margin-left:20px;margin-top:20px; font: normal 12px Arial; color#FFFFFF">. Sheesh.
Well I do not have much experience with tcl but while i was writing a few test cases today all of a sudden the complier kept saying Missing '}' and i had to go through like atleast 50 to 60 brace pairs to make sure all were right, and after spending about 1.5 hours on this mistake it was really annoyed to find out that i forgot to close my comment with a '}'
so the following is the code in my comment
#test XmlDAOTest-1.15 {Test XmlDAO - method - 'ProcessCDATASectionNode'\
So if you see, i have commented the line and i did not close it with the '}' because comments are not supposed to be compiled and checked for syntax, only after i appended a '}' after the '\' the compiler gave me the result. I am using the following
IDE - Eclipse Indigo Version of Tcl - Tcl/Tk 8.5 with tclOO
Version: Indigo Service Release 2 Tcltest, tDom all included
Build id: 20120216-1857
I want to know if this is a Flaw on the side of the IDE or is it inherent to TCL/Tk and if it is a problem in TCl are there anymore like these that you have encountered.
The '\' at the end of the line is also a continuation marker, so it could be pulling the next line into the comment.
e.g.
#puts "1";\
puts "2";
puts "3";
Will output 3 because the 2nd line is treated as part of the comment.
The issue you are seeing is due to Tcl, not your IDE. That being said, it's not a "problem" with Tcl, just an artifact of how the code is parsed. In Tcl, the has symbol only starts a comment in places where it would be valid to start commands and, as such, comments need be parsed at the same time as the rest of the code. Since the code is not "preprocessed" to remove comments, the quotes and braces need to be balanced.
To give you an example of why the parsing is done this way:
set x #abc
In the above line, the value of x is #abc. If comments were preprocessed, the above would convert to just set x and the rest would disappear.
Along the same lines, and another place many people get bitten by with comments:
switch -exact -- $myvalue {
# this is not a comment
"a value" { do something }
"another value { do something }
}
In the above, #, is, and a are all switch cases; you can also look at it this way (which is the same thing)
switch -exact -- $myvalue {
"#" { this }
"is" { not }
"a" { comment }
"a value" { do something }
"another value" { do something }
}
The reason for this is that the inside of a switch statement, where it's looking for case values, is not a valid place for a command. As such, the # is just a normal character the same as any other.
I have a Perl Script which was built on a Linux platform using Perl 5.8 . However now I am trying to run the Perl Script on a Windows platform command prompt with the same Perl version.
I am using this command perl rgex.pl however it gives me one whole chunk of errors which looks to me like it has already been resolved in the script itself. The weird thing is I am able to run another Perl script without problem consisting of simple functions such as print, input etc.
The Code:
#!/usr/bin/perl
use warnings;
use strict;
use Term::ANSIColor;
my $file = "C:\Documents and Settings\Desktop\logfiles.log";
open LOG, $file or die "The file $file has the error of:\n => $!";
my #lines = <LOG>;
close (LOG);
my $varchar = 0;
foreach my $line ( #lines ) {
if ( $line =~ m/PLLog/ )
{
print("\n\n\n");
my $coloredText = colored($varchar, 'bold underline red');
print colored ("POS :: $coloredText\n\n", 'bold underline red');
$varchar ++;
}
print( $line );
}
When I run on the windows command prompt it gives me errors such as:
Unrecognized escape \D passed through at rgex.pl line 7.
=> No such file or directory at rgex.pl line 8.
Please give some advice on the codes please. Thanks.
A \ in a Perl string enclosed in double quotes marks the beginning of an escape sequence like \n for newline, \t for tab. Since you want \ to be treated literally you need to escape \ like \\ as:
my $file = "C:\\Documents and Settings\\Desktop\\logfiles.log";
Since you are not interpolating any variables in the string it's better to use single quotes:
my $file = 'C:\Documents and Settings\Desktop\logfiles.log';
(Inside single quotes, \ is not special unless the next character is a backslash or single quote.)
These error messages are pretty clear. They tell you exactly which lines the problems are on (unlike some error messages which tell you the line where Perl first though "Hey, wait a minute!").
When you run into these sorts of problems, reduce the program to just the problematic lines and start working on them. Start with the first errors first, since they often cascade to the errors that you see later.
When you want to check the value that you get, print it to ensure it is what you think it is:
my $file = "C:\\D....";
print "file is [$file]\n";
This would have shown you very quickly that there was a problem with $file, and once you know where the problem is, you're most of the way to solving it.
This is just basic debugging technique.
Also, you're missing quite a bit of the basics, so going through a good Perl tutorial will help you immensely. There are several listed in perlfaq2 or perlbook. Many of the problems that you're having are things that Learning Perl deals with in the first couple of chapters.