SCPI LAN Measurement - lan

I am trying to com with a scope over LAN that supports SCPI. Link is established I can ;
*RST
*CLS
but I can't do ;
:MEASure:SOURce CH1
it returns zero. To be more clear ;
a = SCPI(host, timeout=0.5)
a.ask('SYST:ERR?');
a.write('*RST'); a.write('*CLS');
a.ask(":MEASure:SOURce CH1");
returns ;
>> SYST:ERR?
<<
>> SYST:ERR?
<<
>> :MEASure:SOURce CH1
<<
>> SYST:ERR?
<<
doing *IDN? retuns successfully.
What might be going on ? It's a OWON XDS device.

Check the device you're communicating with. What terminating characters does it require?
Does Measure command require question mark to indicate a request?
It appears that *RST and *CLS are not working. The response is an error.

Related

How to get exit code of a script launched via system() in C++?

I would like to run a script in an C++ application and capture from it exit code. So I did so in the app:
std::string script_path = "/home/john/script.sh";
int i = system(script_path.c_str());
std::cout << "ERROR: " << i << std::endl;
I wrote a simple script to see if it would catch the error number:
#!/bin/sh
exit 5
but the program shows:
ERROR: 1280
and i don't know why since i'm returning 5 in the script. How could I fix it? I use Linux
How could I fix it? I use Linux
From man 3 system:
RETURN VALUE
If command is NULL, then a nonzero value if a shell is available, or 0 if no shell is available.
If a child process could not be created, or its status could not be retrieved, the return value is -1 and errno is set to indicate the error.
If a shell could not be executed in the child process, then the return value is as though the child shell terminated by calling _exit(2) with
the status 127.
if all system calls succeed, then the return value is the termination status of the child shell used to execute command. (The termination sta‐
tus of a shell is the termination status of the last command it executes.)
In the last two cases, the return value is a "wait status" that can be examined using the macros described in waitpid(2). (i.e., WIFEXITED(),
WEXITSTATUS(), and so on).
You could use:
std::cout << "ERROR: " << ( (i != -1 && i != 127 && WIFEXITED(i)) ? WEXITSTATUS(i) : -1) << std::endl;

Two way communication with process

I have given some compiled program. I want to communicate with it from my bash script by program stdin and stdout. I need two way communication. Program cannot be killed between exchange of information. How I can do that?
Simple example:
Let that program be compiled partial summation (C++) and script results will be squares of that sums. Program:
int main() {
int num, sum = 0;
while(true) {
std::cin >> num;
sum += num;
std::cout << sum << std::endl;
}
}
My script should looks like that:
for i in 1 2 3 4; do
echo "$i" > program
read program to line;
echo $((line * line))
done
If in program I have for(int i = 1; i <= 4; ++i), then I can do something like that:
exec 4< <(./program); # Just read from program
for i in 1 2 3 4; do
read <&4 line;
echo "sh: $((line * line))";
done
For more look here. From the other hand, if in program I have std::cout << sum * sum;, then solution could be:
exec &3> >(./program); # Write to program
for i in 1 2 3 4; do
echo "$i" > &3
done
My problem is two way communication with other process / program. I don't have to use exec. I cannot install third party software. Bash-only solution, without files, will be nice.
If I run other process, it will be nice to know pid to kill that at the end of script.
I think about communication with two or maybe three processes in the future. Output of firs program may dependents on output of second program and also in second side. Like communicator of processes.
However, I cannot recompile programs and change something. I have only stdin and stdout communication in programs.
If you have bash which is newer than 4.0, you can use coproc.
However, don't forget that the input/output of the command you want to communicate might be buffered.
In that case you should wrap the command with something like stdbuf -i0 -o0
Reference: How to make output of any shell command unbuffered?
Here's an example
#!/bin/bash
coproc mycoproc {
./a.out # your C++ code
}
# input to "std::cin >> num;"
echo "1" >&${mycoproc[1]}
# get output from "std::cout << sum << std::endl;"
# "-t 3" means that it waits for 3 seconds
read -t 3 -u ${mycoproc[0]} var
# print it
echo $var
echo "2" >&${mycoproc[1]}
read -t 3 -u ${mycoproc[0]} var
echo $var
echo "3" >&${mycoproc[1]}
read -t 3 -u ${mycoproc[0]} var
echo $var
# you can get PID
kill $mycoproc_PID
output will be
1
3
6
If your bash is older than 4.0, using mkfifo can do the same thing like:
#!/bin/bash
mkfifo f1 f2
exec 4<> f1
exec 5<> f2
./a.out < f1 > f2 &
echo "1" >&4
read -t 3 -u 5 var
echo $var
rm f1 f2
Considering that your C++ program reads from standard output, and prints to standard output, it's easy to put it inside a simple chain of pipes:
command_that_writes_output | your_cpp_program | command_that_handle_output
In your specific case you probably need to modify the program to only handle one single input and writing one single output, and remove the loop. Because then you can do it very simple, like this:
for i in 1 2 3 4; do
result=`echo $i | ./program`
echo $((result * result))
done

Shell Script to generate next hundred ip addresses

If I have an IP address say 192.168.1.2, I need to generate the next 100 IPs such that it keeps adding to the base ip.
I tried to execute echo 192.168.1.{2..102} this works fine but I need a generic code that can generate as many IP addresses specified with the base IP address using Shell Script.
Something like:
#!/bin/bash
i=1
while (( i <= 100 ))
do
echo "x.y.z.$i"
i=$((i + 1))
done
You can use a for to iterate through a list created by the command seq. Then, just modify the numbers in seq as first and last number
#!/bin/bash
START=0
END=100
for I in $(seq $START $END)
do
echo "192.168.0.$I"
done
If I need to change up to second octet then I should be able to change.
For example. 198.168.X.Y. I need to generate the ip for X and Y
If I need to change up to three octets then I should be able to change.
Am looking for a solution for this. seq -f 198.168.1.%g 1 100 works fine, need a script that can change the other octets
IP addresses are, of course, simply unsigned 32 bit numbers. However they are usually expressed as bytes, in decimal, with dots between the numbers.
So, if you need to use this "dotted quad" representation you can just convert the starting one back to an integer, count out how many you want, and for each one you count up, print it back as a dotted quad.
With any shell supporting arithmetic expressions (with bitwise operators, and for added convenience, arrays), it's easy:
#!/bin/ksh
ip="192.168.240.240"
num=100
set -A iparr $(echo $ip | sed 's/\./ /g')
nip=$((iparr[0] << 24))
nip=$((nip | iparr[1] << 16))
nip=$((nip | iparr[2] << 8))
nip=$((nip | iparr[3]))
lnip=$((nip + num))
while [ $nip -lt $lnip ]; do
let $((nip++))
iparr[0]=$((nip >> 24))
iparr[1]=$(((nip >> 16) & 255))
iparr[2]=$(((nip >> 8) & 255))
iparr[3]=$((nip & 255))
printf "%d.%d.%d.%d\n" ${iparr[0]} ${iparr[1]} ${iparr[2]} ${iparr[3]}
done
(It's not so easy with an older shell though -- and neither awk nor expr do bitwise operations on integers very easily. But then maybe the tool you're feeding these numbers to will accept plain integers, or hex numbers, so you may not really need to use dotted quad notation.)

Until Loop not working as expected

I'm currently learning Linux and as an homework, we have to create a few basic shell scripts. Nothing especially complicated but this one is giving me headaches. Here's my code :
until [ "$toPrint" == 'fin' ]
do
echo "Enter file name to print out :" ; read toPrint
sh ./afficher.sh "$toPrint"
done
Basically, I have another script called afficher.sh (I'm french so don't mind the french language used) and it reads whatever file name it gets as a parameter. However, the moment I type "fin", everything is supposed to stop except it still tries to print the file called "fin". I read a bit about the until loop on Internet and once it becomes True, it should stop, which is not my case...
Personally, I'd implement this like so -- with a while loop, not an until loop, and checking for the exit condition separately and explicitly:
while true; do
echo "Enter file name to print out :" ; read toPrint
[ "$toPrint" = fin ] && break
sh ./afficher.sh "$toPrint"
done
If you really want to use the loop's condition, you can do that:
while echo "Enter file name to print out :";
read toPrint &&
[ "$toPrint" != fin ]; do
sh ./afficher.sh "$toPrint"
done
...but personally, I'm less fond of this on aesthetic grounds.
You check the condition at the top of the loop, but you enter the value in the middle of the loop. The next thing you do after reading the value is always pass it to afficher.sh and then once that is done you check its value to see if you should stop. If you don't want to run afficher.sh on the fin value, you'll need to make sure your control flow allows you to do the comparison before you invoke afficher.sh.

raw input mode on stdin in Cygwin/Mintty

I want to get my stdin into raw input mode in Cygwin/Mintty. How do I do that? Right now, it is line-buffered. With raw input mode, I mean that read returns on every single entered character.
I would prefer to do that without any further dependencies. I.e. I guess this probably can be done by linking against some libs from Cygwin, however, if it is possible, I'd like to avoid that.
Some search results: libuv issue, libuv win/tty.c, Cygwin tty.cc, Cygwin fhandler_tty.cc, Cygwin post (non-blocking stdin), Mintty issue, Msysgit issue
I tried via SetConsoleMode, but that only works for the Windows console, not for Mintty. I.e. this code:
// Setting terminal to raw mode...
HANDLE hStdin;
DWORD mode;
//hStdin = GetStdHandle(STD_INPUT_HANDLE);
hStdin = (HANDLE) _get_osfhandle(STDIN_FILENO);
if (GetFileType(hStdin) == FILE_TYPE_CHAR) {
cout << "stdin is file type char" << endl;
GetConsoleMode(hStdin, &mode);
if (
!SetConsoleMode(
hStdin,
mode & ~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT))
) {
cerr << "Cannot set stdin to raw mode" << endl;
// ignore...
}
}
Does system( "stty -raw" ); work?

Resources