Search code examples
clinuxbashexpectrm

system command rm not working in expect program


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?


Solution

  • 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.