how is the following UNIX command interpreted - shell

How is this command interpreted:
cat file.txt |
If no arguments are passed after the pipe, can you explain at the C level why and how a new embedded command line interface is opened?

It's not the end of the command. The shell is waiting for the rest of it. If you force it, you get Syntax error: end of file unexpected

Related

Command Substitution and variables

I'm running into an issue with command substitution that I'd like help with. I have a few processes that create a text file with commands that need to be executed.
File1.txt
Command_ID|Command_Name|Command
112121|Export XML Components|/Scripts/Export_XML.sh "Argument1" "Argument2"
112122|Test XML integrity|/Scripts/Test_XML.sh "Argument1" "Argument2" "Argument3"
My Script to execute these commands reads File1.txt and tries to execute the command in the third column using the following Command substitution. The goal here is to read and execute the commands sequentially and update a table with their return strings and return codes. I also have logic in the script to stop processing if a non-zero return code is encountered and store the current line number. This way the script can be restarted from the failed line after the issue has been addressed
VAR_File=/files/File1.txt
while IFS=$'|' read -r -a myArray
do
echo "${myArray[2]}"
VAR_Command="${myArray[2]}"
VAR_Return_String=$("${VAR_Command}")
VAR_Return_Code=$?
done < ${VAR_File}
The commands where the Arguments have double quotes are not being executed correctly.
What am I doing wrong and how can I fix this?
Thanks
In your script, VAR_Command is set to some string from File1.txt like /Scripts/Export_XML.sh "Argument1" "Argument2".
When running $(${VAR_Command}" with this string, the shell attempts to execute a script named Export_XML.sh "Argument1" "Argument2" (with quotes inside the file name), rather than the script Test_XML.sh to which the arguments "Argument1" and "Argument2" are passed.
If you remove the quotes by replacing $("${VAR_Command}") by $(${VAR_Command}), your code will work as expected.

How to write a multi line macro in ~/.lldbinit?

I want to write this macro in ~/.lldbinit:
command regex pxml 's/(.+)/p xmlElemDump(stdout, %1, xmlDocGetRootElement(%1))/' -h "Dump the contents of an XML tree."
But it is too long and I want to break it into multi lines like this:
command regex pxml
's/(.+)/p xmlElemDump(stdout, %1, xmlDocGetRootElement(%1))/'
-h "Dump the contents of an XML tree."
or
command regex pxml\
's/(.+)/p xmlElemDump(stdout, %1, xmlDocGetRootElement(%1))/'\
-h "Dump the contents of an XML tree."
Unfortunately both of them cause this error:
Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.
Terminate the substitution list with an empty line.
How can I break the macro into multi lines?
lldb doesn't have a continuation character. That would be tricky in some of the free-form commands, particularly the "print" command. But would be useful in these cases. Feel free to file a bug requesting this with the lldb/llvm bug tracker: https://llvm.org/bugs/.
In most cases where a command has a few options, then takes a set of inputs, the command can enter a little mini-editor for the set of inputs. This is true for command regex. So in command line lldb, you would see:
(lldb) command regex whatever -h "some help" -s "some syntax"
Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.
Terminate the substitution list with an empty line.
> s/First/Replacement/
> s/Second/Replacement/
>
The command source function that also reads the .lldbinit works by feeding the command file as a stream to the interpreter. So you need to mock up what the command line does:
command regex whatever -h "some help" -s "some syntax"
s/First/Replacement/
s/Second/Replacement/
That's not quite right, there has to be a blank line in the input file after the last substitution to terminate the substitutions, but I can't convince this markup to include it in the code block. But you get the idea.
I write aliases in a .py file and import it to ~/.lldbinit.
In python file, we can use continuation character.
e.g.)
you would save the following code as something.py
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("command regex pos 's/(.*)?-op?(.*)/ exp -l swift -O %2 -- %1/'\
's/(.*)/ exp -l swift -O -- %1/'")
write this in ~/.lldbinit
command script import <path>/something.py

Two commands in one script ubuntu terminal

I have two commands:
#!/bin/bash
python /srv/django/manage.py shell; execfile('/home/usr/myscript.py')
I want to use them in one script scr.sh. However as it is, I get errors.
CommandError: Command doesn't accept any arguments
/home/usr/project.sh: line 7: syntax error near unexpected token
`'/home/usr/myscript.py''
where myscript.py is what the code I want running when the python shell appears. How could I go about achieving this?
Thanks!
What was happening here is that ';' symbol will wait until something is performed/run in the shell. The correct syntax would be
#!/bin/bash
python /srv/django/manage.py shell <<EOF\ execfile('myscript.py') EOF

Output of $(3-1) in bash

I found one thing I can not explain in bash.
Command:
$(3-1)
3-1: command not found
If I do it step by step, it will show as follows:
3-1
3-1: command not found
3-1: command not found
3-1:: command not found
Double colons there. Why is the difference?
3-1 is not found. The error message you get is sent to standard error, not standard output. So, $(3-1) is not running
3-1: command not found
It is running 3-1 and failing. If you try to run the error message, the first word is taken as the command, the rest are the arguments. The command 3-1: is not found either, hence the error message with two colons.
what are you going to do with 3-1? if you want to execute it I doubt you have program 3-1 or 2. try like this:
n=$((3-1))
echo $((3-1))
I think explanation is needed here:
if you write in bash new line
do_smth
it assumes you want to execute a program. The $(do_smth) mean: execute a program do_smth and catch the output. so, if you write in bash new line
$(do_smth)
it assumes you want to execute do_smth, take an output from command and execute command with name it get. $(( $do_smth )) is another. It assumes $do_smth is a mathematical expression and affords you to calculate c-like math expression.
Your "step by step" breakdown is wrong because you assumed that the first "command not found" error message would become the result of the $() and therefore be re-parsed as a command. This doesn't happen because $() only captures standard output (fd 1) and the "command not found" message is printed to standard error (fd 2).
If you run
$(3-1 2>&1)
you might get something more like what you're expecting. (I can't reproduce your result exactly because my bash error messages don't look quite like yours.)
you input:
foo
output:
foo: command not found
you input :
foo bar
output:
foo: command not found
so bash thinks the space separating commands/parameters. If the command you gave with :, you get it in input too:
input:
foo:
output:
foo:: command not found
replace foo with 3-1, you find the answer.
When you type any command which bash cannot find, you get an error message of the form
bash: <cmd>: command not found
So if you type 3-1, you get
$ 3-1
bash: 3-1: command not found
If you type 3-1:, you get
$ 3-1:
bash: 3-1:: command not found
The shell sees this:
situation 1
stdin- "$(3-1)" ( run non existent command "3-1" in a subshell ... )
Command- "3-1"
Arguments-
error- 3-1
reply- "3-1" ": command not found"
situation 2
stdin- "3-1:" "command" "not" "found"
Command- "3-1:"
(note that the ":" you typed is seen as part of the command)
Arguments- "command" "not" "found"
error- 3-1:
reply- "3-1:" ": command not found"
(^---^ and this is where the double colon comes from)
As you can see, the shell does not reply with a double colon at all!
it echoes your "3-1:" and it adds ": reply"

Bash for loop error

I am trying out a simple bash script using for loop, and kept getting the following error:
'/test.sh: line 2: syntax error near unexpected token `do
'/test.sh: line 2: `do
The following is the code that is being used...
for animal in dog cat elephant
do
echo "There are ${animal}s.... "
done
However, when I tried on other machines.. it is working no problem.
Please help.
Your test.sh script has Windows-style line endings. The shell sees each \r\n sequence as a \r character at the end of the line.
The shell is seeing do\r rather than do. Since \r sends the cursor to the beginning of the line, that's why you're seeing the quotation mark at the beginning of the line. Try
./test.sh 2>&1 | cat -A
to see what's actually in the error message.
Filter your test.sh script through something like dos2unix to correct the line endings. (Be sure to read the man page first; dos2unix, unlike most text filters, overwrites its input file.)
This is a common problem on Cygwin. Did you use a Windows editor to create the script?

Resources