system command rm not working in expect program - c

I have a code (1) that is supposed to execute test in another code (its a pseudo-bash). This code (1) is wrote using the "expect" for the 'user simulation'.
The problem is when this code (1) execute a system ( on this case, system "rm totoExpect.txt titiExpect.txt") when its just doesnt find the titiExpected.txt, but is there!
There is nothing different between the two files, even the permissions are the same, i cant think in a reason that doesnt work.
Here is the part of the code (1) where the problem raises:
# test 5
proc t5 {} {
send "ls > totoExpect.txt\r"
send "cat < totoExpect.txt | wc -l > titiExpect.txt\r"
send "cat titiExpect.txt\r"
expect -re "(0|1|2|3|4|5|6|7|8|9)+.*>" { ok 5; } default { abort 5 }
system "rm totoExpect.txt titiExpect.txt"
}
And the Error message:
ls > totoExpect.txt
out: totoExpect.txt
seq[0]: 'ls'
-----3
ensishell>c
***** TEST 5 ok
rm: não foi possível remover "titiExpect.txt": Arquivo ou diretório não encontrado
child process exited abnormally
while executing
"system "rm totoExpect.txt titiExpect.txt""
(procedure "t5" line 6)
invoked from within
"t5"
("eval" body line 1)
invoked from within
"eval "t$t;" "
("foreach" body line 1)
invoked from within
"foreach t {0 1 2 3 4 5 6 7} { eval "t$t;" } "
invoked from within
"expect_user {
-timeout 30 "auto\n" {
puts "AUTO:\n";
foreach t {0 1 2 3 4 5 6 7} { eval "t$t;" }
}
-timeout 30 -re "(\[0123456789 \]+)\..."
(file "./testshell.expect" line 99)
make: ** [test] Erro 1
Where "rm: não foi possível remover "titiExpect.txt": Arquivo ou diretório não encontrado"
means "rm: it was not possible to remove "titiExpect.txt": file or directory not found" (sorry about that...)
and this is the ls -l just after the error message (so titiExpect.txt shouldnt be there):
-rwxrwxr-x 1 fernando fernando 273 Out 23 17:53 #Makefile#
-rwxrwxr-x 1 fernando fernando 6238 Nov 5 21:18 #ensishell.c#
-rwxrwxr-x 1 fernando fernando 1271 Out 24 20:30 #readcmd.h#
-rwxrwxr-x 1 fernando fernando 3250 Nov 5 21:07 #testshell.expect#
-rwxrwxrwx 1 fernando fernando 303 Out 24 20:21 Makefile
drwxrwxr-x 2 fernando fernando 4096 Nov 4 19:06 SEPC shell
-rw-rw-r-- 1 fernando fernando 193453 Out 18 18:25 Sujet_shell.pdf
-rwxrwxr-x 1 fernando fernando 25451 Nov 5 21:17 ensishell
-rwxrwxrwx 1 fernando fernando 6238 Nov 5 20:32 ensishell.c
-rw-rw-r-- 1 fernando fernando 10664 Nov 5 21:17 ensishell.o
-rwxrwxr-x 1 fernando fernando 7251 Nov 4 00:33 foo
-rw-rw-r-- 1 fernando fernando 173 Nov 4 00:33 foo.c
-rw-rw-r-- 1 fernando fernando 16 Nov 4 01:15 in.txt~
-rwxrwxrwx 1 fernando fernando 6603 Out 23 00:37 readcmd.c
-rwxrwxrwx 1 fernando fernando 1271 Out 23 01:24 readcmd.h
-rwxrwxrwx 1 fernando fernando 1271 Out 23 00:37 readcmd.h~
-rw-rw-r-- 1 fernando fernando 11216 Nov 5 21:17 readcmd.o
-rwxrwxrwx 1 fernando fernando 3250 Nov 5 20:41 testshell.expect
-rwx------ 1 fernando fernando 1263 Nov 5 12:43 toto.txt
The worst problem is this code is not supposed to be modified, but its seems to me that is the programs fault this fail. (in fact, commenting the line solve the problem..)
Any ideas?

Look.
# test 5
proc t5 {} {
send "ls > totoExpect.txt\r"
send "cat < totoExpect.txt | wc -l > titiExpect.txt\r"
send "cat titiExpect.txt\r"
expect -re "(0|1|2|3|4|5|6|7|8|9)+.*>" { ok 5; } default { abort 5 }
system "rm totoExpect.txt titiExpect.txt"
}
The first send crates a file named totoExpect.txt\r.
The second send generates a file named titiExpect.txt\r. The cat part actually fails, because there is no file totoExpect.txt, but since the command is part of a pipe, and not the last command in said pipe, expect will not catch that as an error. (All you'll see is that the titiExpect.txt\r file will be empty.)
The \r above is the CR character, and probably the reason you have missed it. In Linux, it is perfectly allowed character in file names (as only / and \0 are forbidden). Just remove it from your test and you'll find it works fine.
Or, if you insist on keeping it, then keep it consistently:
# test 5
proc t5 {} {
send "ls > totoExpect.txt\r"
send "cat < totoExpect.txt\r | wc -l > titiExpect.txt\r"
send "cat titiExpect.txt\r"
expect -re "(0|1|2|3|4|5|6|7|8|9)+.*>" { ok 5; } default { abort 5 }
system "rm totoExpect.txt\r titiExpect.txt\r"
}
Finally, when removing files, it is recommended to use the -f flag, so rm does not complain if one of the files happens to not exist.
My suggestion is to rewrite that test as
# test 5
proc t5 {} {
send "ls > totoExpect.txt"
send "cat < totoExpect.txt | wc -l > titiExpect.txt"
send "cat titiExpect.txt"
expect -re "(0|1|2|3|4|5|6|7|8|9)+.*>" { ok 5; } default { abort 5 }
system "rm -f totoExpect.txt titiExpect.txt"
}
eradicating those erratic \rs.

Related

How to remove space for files in directory

I have these 2 space files in the below directory and want to remove space for these filenames
/home/sterlingadmin/
-rw-rw-r-- 1 sterlingadmin sterlingadmin 99 Jan 3 14:32 output test.txt
-rw-rw-r-- 1 sterlingadmin sterlingadmin 24 Dec 4 10:00 space test.txt
I try to use below find command to remove space for the files but its not reflecting for the files
[sterlingadmin#$
find -name "* *" |tr -d "[:blank:]"
./outputtest.txt
./delspace.txt
[sterlingadmin#$
ls -lrt
-rw-rw-r-- 1 sterlingadmin sterlingadmin 99 Jan 3 14:32 output test.txt
-rw-rw-r-- 1 sterlingadmin sterlingadmin 24 Dec 4 10:00 space test.txt'
Please advise if any solution for this issue. thank you.

unix shell : create different tar files using a string in a array

We have services that generate files named with modules names. For ex., acqDou module generates
acqDou_0001.out
acqDou_08981.out
acqDou_23423.out
The acq_cheat module generates files with almost same name, but last numbering is a bit diffrent.
My Requirment is to tar these files on the basis of module names, one tar file per module, such as acqDou.tar and acq_cheat.tar
Below is the programm I attmepted:
cd /home/swap/output/outfiles
for i in *;
do
j=`echo $i | grep -v 'out$'`
if [ -z $j ];
then continue;
fi
count1=$(echo $i | tr -d -c '_' | wc -m)
if [ $count1 -eq 2 ]
then
two=`ls -1 $i | cut -d'_' -f2 | cut -d'.' -f1 | uniq`
else
two=`ls -1 $i | cut -d'_' -f1 | cut -d'.' -f1 | uniq`
fi
_FILE="${_FILE} $two"
done
_FILE2=`echo "${_FILE[#]}" | tr ' ' '\n' | sort -u | tr '\n' ' '`
echo "${_FILE2}"
for m in "${_FILE2}"
do
ls -lrt *${m}*.x
tar -cpf $m.tar /home/swap/output/outfiles/*${m}*
done
}
In case you can distinguish the files by their name, the solution can be so simple straightforward:
tar cf acqDou.tar acqDou*.out*
tar cf acq_cheat.tar acq_cheat*.out*
If there are several such modules, you can even apply a simple for loop to process them:
for m in acqDou acq_cheat
do
tar cf $m.tar ${m}*.out*
done
Make tars for all possible module types present in the directory - in one shot.
lets say you have modules named as.. acqDou, acqDumb, acqcheat, acqfunny - In module_XXXX.out format.
something which may looks like this, as shown below. So i got 4 modules and 500 files of each of them in the directory. They all are empty, but it doesn't matter.
>Wed Oct 05|01:15:13|gaurav#[STATION]:/root/ga/scripts/temp/tmp % ls -lrtha *.out|head -7 ; echo ; ls -lrtha |tail -8
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDou_0.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDumb_0.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqcheat_0.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqfunny_0.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDou_1.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDumb_1.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqcheat_1.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDumb_498.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqcheat_498.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqfunny_498.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDou_499.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDumb_499.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqcheat_499.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqfunny_499.out
drwxrwxr-x. 2 gaurav gaurav 64K Oct 5 01:14 .
>Wed Oct 05|01:15:30|gaurav#[STATION]:/root/ga/scripts/temp/tmp %
In order to achieve the objective:
we can list the files, strip off the numbers (using sed), sort and unique the list (which gives the possible present module names in the directory) and then feed it to a while loop, to read module names one by one .. and then generate our output tarfile, module name wise and having files of that module only.
Here is the command:
ls *.out |sed 's/[0-9]//g'|sort|uniq|sed 's/_.out//g'|while read module
do
tar -cvf ${module}.tar ${module}*
done
We get something like this, once we finish.
>Wed Oct 05|01:16:43|gaurav#[STATION]:/root/ga/scripts/temp/tmp % ls -lrth *.tar
-rw-rw-r--. 1 gaurav gaurav 260K Oct 5 01:16 acqcheat.tar
-rw-rw-r--. 1 gaurav gaurav 260K Oct 5 01:16 acqDou.tar
-rw-rw-r--. 1 gaurav gaurav 260K Oct 5 01:16 acqDumb.tar
-rw-rw-r--. 1 gaurav gaurav 260K Oct 5 01:16 acqfunny.tar
>Wed Oct 05|01:16:48|gaurav#[STATION]:/root/ga/scripts/temp/tmp %
4 tar files have been created, with their module names. And it contains its respective module files. Let us see by using tar -tvf command. I will run it on all tar files and just take 2 lines as output, per file.
>Wed Oct 05|01:18:29|gaurav#[STATION]:/root/ga/scripts/temp/tmp % ls *.tar|while read file
do
echo ;echo "Looking inside file: $file"
tar -tvf $file|head -2
done
Looking inside file: acqcheat.tar
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqcheat_0.out
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqcheat_100.out
Looking inside file: acqDou.tar
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqDou_0.out
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqDou_100.out
Looking inside file: acqDumb.tar
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqDumb_0.out
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqDumb_100.out
Looking inside file: acqfunny.tar
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqfunny_0.out
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqfunny_100.out
>Wed Oct 05|01:18:42|gaurav#[STATION]:/root/ga/scripts/temp/tmp %
We do really have 500 files in each tar file. Let us just confirm that too.
>Wed Oct 05|01:18:42|gaurav#[STATION]:/root/ga/scripts/temp/tmp % ls *.tar|while read file
do
echo ; echo "File count in tar file: $file"
tar -tvf $file|wc -l
done
File count in tar file: acqcheat.tar
500
File count in tar file: acqDou.tar
500
File count in tar file: acqDumb.tar
500
File count in tar file: acqfunny.tar
500
>Wed Oct 05|01:20:03|gaurav#[STATION]:/root/ga/scripts/temp/tmp %
Cheers,
Gaurav

tr not impacting file command output

If I run:
$ ls -l /tmp
total 16
drwxr-xr-x 2 noaccess noaccess 177 Nov 18 09:53 hsperfdata_noaccess
drwxr-xr-x 2 root root 117 Nov 18 09:53 hsperfdata_root
I get the expected result running:
]$ ls -l /tmp | tr -s '[:space:]'
total 16
drwxr-xr-x 2 noaccess noaccess 177 Nov 18 09:53 hsperfdata_noaccess
drwxr-xr-x 2 root root 117 Nov 18 09:53 hsperfdata_root
Yet tr will not impact file output:
$ file /tmp/dummy
/tmp/dummy: empty file
$ file /tmp/dummy | tr -s '[:space:]'
/tmp/dummy: empty file
(the same if I use [:blank:])
I was expecting:
$ file /tmp/dummy | tr -s '[:space:]'
/tmp/dummy: empty file
Am I misusing file? tr? Must I awk? I'm using bash 3.2.51 on SunOS 5.10 and would like to tell XML and gz files apart.
The Solaris 5.10 version of file is producing output that uses tabs instead of spaces:
$ touch /tmp/dummy
$ file /tmp/dummy | cat -vet
/tmp/dummy:^Iempty file$
$
In this case, tr -s squashes a single tab character down to a single tab character...

prints out wrongly,positions of characters mixed up, whats wrong,loop

Mycode prints many lines with 9 elements each. If the line (first element) starts with 'd', then do not print out the rest elements of the line. so if you try ls -l | mycode it will delete lines starting with 'd'. BUT for some reasons the elements move left by one if for example:
ls -l
drwxrwxrwx 2 alk lotus 35 Sep 23 19.00 directory1
-rwxrwxrwx 2 alk lotus 345 Sep 23 13.00 file1
drwxrwxrwx 3 alk lotus 245 Sep 23 19.20 directory2
drwxrwxrwx 24 alk lotus 15 Sep 23 12.00 directory3
-rwxrwxrwx 5 alk lotus 25 Sep 23 14.00 file2
-rwxrwxrwx 8 alk lotus 25 Sep 23 10.00 file3
ls -l | mycode
-rwxrwxrwx 2 alk lotus 345 Sep 23 13.00
file1 -rwxrwxrwx 5 alk lotus 25 Sep
23 14.00 file2 -rwxrwxrwx 8 alk lotus 25 Sep
23 10.00 file3
So why file2 file1 goes down? I wanna that file to stay in his place....After that all positions are mixed up there....Help please to fix this...
my code here:
The logic in your code seems not correct. What you want to do is to remove lines that starts with d, however in the code you it does something else.
I'm presenting you an example which is expected to work, which shall replace your code example:
while (fgets(string, 1024, stdin))
if (string[0] != 'd')
printf("%s", string); // don't use puts cuz fgets would store the newline
I don't understand why you aren't just using only fgets:
for (i=0; i<9;i++){
if (NULL != fgets(string,1024,stdin)) {
if (string[0] != 'd'){
printf("%s\n", string);
}
}
else break;
}

Unix `find` command that returns path and whether or not it's a file/directory?

When you do ls -la it returns each path along with info of whether or not it's a file/directory:
$ ls -la
drwxr-xr-x 11 viatropos staff 374 Jan 21 21:24 .
drwxr-xr-x 41 viatropos staff 1394 Feb 2 00:48 ..
-rw-r--r-- 1 viatropos staff 43 Jan 21 21:23 .gitignore
-rw-r--r-- 1 viatropos staff 43 Jan 21 21:23 .npmignore
-rw-r--r-- 1 viatropos staff 647 Jan 21 21:23 README.md
-rw-r--r-- 1 viatropos staff 3069 Feb 5 20:17 index.js
drwxr-xr-x 8 viatropos staff 272 Feb 5 20:06 node_modules
-rw-r--r-- 1 viatropos staff 291 Jan 21 21:24 package.json
drwxr-xr-x 4 viatropos staff 136 Jan 21 21:23 test
Is there a way to do this using the find command (and glob * functionality)? So, finding all paths within node_modules and having it return the path and whether or not it's a file directory? Something like:
$ find node_modules -name 'lib/*'
d node_modules/express/lib/
f node_modules/express/lib/index.js
...
How about find ... -printf '%y %p\n'? (This is probably a GNU find extension, though.)
Try this script, I called it "findfl". The "mtime" clause finds files changed in the last 3 days.
Directories will have "/" appended.
#!/bin/sh
# find files produced recently, matching input pattern
[ $1 ] || { echo "Usage: findfl <file-name-pattern>" ; exit ; }
TOPDIR=/home/usr/fred #the directory you want to search
echo "Searching $TOPDIR"
find . -mtime -3 -name *$1* 2>/dev/null | xargs -n 99 ls -lptr | sed "s! ./! $TOPDIR/!g"

Resources