When I use scp command through expect, asterisk can not recognized - linux

Hello I have a one problem in linux shell
I write a scp script using expect and the script is like this.
#!/bin/sh
expect -c "spawn scp /tmp/data/*2017-06-14*.log2 id#localhost:~/"\
-c "expect -re \"password\" "/
-c "sleep 1" \
-c "send \"password\r\""\
-c "interact"
and result of execution shows error message.
/tmp/data/*2017-06-14*.log2 : No such file or directory
But When not use expect, scp execution is success
[user#localhost]# scp /tmp/data/*2017-06-14*.log2 id#localhost:~/"\
How can i solve this problem?

Expect does not understand shell's syntax. You can:
spawn sh -c "scp /tmp/data/*2017-06-14*.log2 id#localhost:~/"
or
spawn sh -c {scp /tmp/data/*2017-06-14*.log2 id#localhost:~/}
komar's answer using glob would not always work. See following example:
bash-4.4# expect
expect1.1> system pwd
/root/tmp/tcl
expect1.2> system ls -l
total 0
-rw-r--r-- 1 root root 0 Jun 16 10:55 a b
-rw-r--r-- 1 root root 0 Jun 16 10:55 c d
expect1.3> spawn ls -l [glob *]; expect eof
spawn ls -l {a b} {c d}
ls: cannot access {a b} {c d}: No such file or directory
expect1.4> spawn sh -c "ls -l *"; expect eof
spawn sh -c ls -l *
-rw-r--r-- 1 root root 0 Jun 16 10:55 a b
-rw-r--r-- 1 root root 0 Jun 16 10:55 c d
expect1.5>

You need globbing in expect/tcl style:
expect -c "spawn scp [glob /tmp/data/*2017-06-14*.log2] id#localhost:~/"

Related

Get clean list of file sizes and names using SFTP in unix

I want to fetch list of files from a server using SFTP one by one only if their size is less than 1 GB.
I am running the following command :
$sftp -oIdentityFile=/home/user/.ssh/id_rsa -oPort=22 user#hostname >list.txt <<EOF
cd upload/Example
ls -l iurygify*.zip
EOF
This results in:
$cat list.txt
sftp> cd upload/Example
sftp> ls -l iurygify*.zip
-rwxrwx--- 0 300096661 300026669 0 Mar 11 16:38 iurygify1.zip
-rwxrwx--- 0 300096661 300026669 0 Mar 11 16:38 iurygify2.zip
I could then use awk to calculate get the size and filename which I can save into logs for reference and then download only those files which meet the 1 GB criteria.
Is there any simpler approach to accomplish getting this file list and size? I want to avoid the junk entires of the prompt and commands in the list.txt and do not want to do this via expect command.
We are using SSH key authentication
You could place your sftp commands in a batch file and filter the output - no need for expect.
echo 'ls -l' > t
sftp -b t -oIdentityFile=/home/user/.ssh/id_rsa -oPort=22 user#hostname | grep -v 'sftp>' >list.txt
Or take it a step further and filter out the "right size" in the same step:
sftp -b t -oIdentityFile=/home/user/.ssh/id_rsa -oPort=22 user#hostname | awk '$1!~/sftp>/&&$5<1000000000' >list.txt
Maybe using lftp instead of sftp ?
$ lftp sftp://xxx > list.txt <<EOF
> open
> ls -l
> EOF
$ cat list.txt
drwxr-xr-x 10 ludo users 4096 May 24 2019 .
drwxr-xr-x 8 root root 4096 Dec 20 2018 ..
-rw------- 1 ludo users 36653 Mar 31 19:28 .bash_history
-rw-r--r-- 1 ludo users 220 Mar 21 2014 .bash_logout
-rw-r--r-- 1 ludo users 362 Aug 16 2018 .bash_profile
...

Why file is not created as owned by a specific user i designated

I have a php script that will collection data and write log into a file, the directory belongs to an user called 'ingestion' and a group called 'ingestion'. I was using the command
sudo -u ingestion php [script] &>> /var/log/FOLDER/adapter.log
The owner and group of FOLDER is ingestion. However, the created adapter.log still belongs to root user and root group, how is this possible?
Your file is created by the bash running as root, not by the process that you run via sudo as ingestion.
That's because the >> foo is part of the command line, not of the process started by sudo.
Here:
#foo.sh
echo foo: `id -u`
Then:
tmp root# sudo -u peter bash foo.sh > foo
tmp root# ls -l foo
-rw------- 1 root staff 9 Mar 2 18:52 foo
tmp root# cat foo
foo: 501
You can see that the file is created as root but the foo.sh script is run as uid 501.
You can fix this by running e.g.:
tmp root# sudo -u peter bash -c "bash foo.sh > foo"
tmp root# ls -l foo
-rw------- 1 peter staff 9 Mar 2 18:54 foo
tmp root# cat foo
foo: 501
In your case, of course, replace "..." with your php command.

How do I use variable substitution in a remote ssh command when the variable value has spaces in it?

I've got the following test script:
#!/bin/bash
ssh -o StrictHostKeyChecking=no root#192.168.1.10 'ls -l "aaa bbb.txt"'
domain="aaa bbb.txt"
ssh -o StrictHostKeyChecking=no root#192.168.1.10 \'ls -l "${domain}"\'
The first command without the $domain variable works fine. Returns:
-rw-rw-rw- 1 root root 7 Nov 21 22:49 aaa bbb.txt
What I can't figure out is the second command. Running it returns the following from the remote server: bash: ls -l aaa bbb.txt: command not found
If I leave off the escaped backticks (ssh -o StrictHostKeyChecking=no root#192.168.1.10 ls -l "${domain}") I get the following error:
ls: cannot access 'aaa': No such file or directory
ls: cannot access 'bbb.txt': No such file or directory
How can I use variable substitution with spaces in the variable value in a remote ssh command?
Thanks.

why sh softlink to bash doesn't work? [duplicate]

I have a shell script which uses process substitution
The script is:
#!/bin/bash
while read line
do
echo "$line"
done < <( grep "^abcd$" file.txt )
When I run the script using sh file.sh I get the following output
$sh file.sh
file.sh: line 5: syntax error near unexpected token `<'
file.sh: line 5: `done < <( grep "^abcd$" file.txt )'
When I run the script using bash file.sh, the script works.
Interestingly, sh is a soft-link mapped to /bin/bash.
$ which bash
/bin/bash
$ which sh
/usr/bin/sh
$ ls -l /usr/bin/sh
lrwxrwxrwx 1 root root 9 Jul 23 2012 /usr/bin/sh -> /bin/bash
$ ls -l /bin/bash
-rwxr-xr-x 1 root root 648016 Jul 12 2012 /bin/bash
I tested to make sure symbolic links are being followed in my shell using the following:
$ ./a.out
hello world
$ ln -s a.out a.link
$ ./a.link
hello world
$ ls -l a.out
-rwx--x--x 1 xxxx xxxx 16614 Dec 27 19:53 a.out
$ ls -l a.link
lrwxrwxrwx 1 xxxx xxxx 5 May 14 14:12 a.link -> a.out
I am unable to understand why sh file.sh does not execute as /bin/bash file.sh since sh is a symbolic link to /bin/bash.
Any insights will be much appreciated. Thanks.
When invoked as sh, bash enters posix
mode after the startup files are read. Process substitution is not recognized in posix mode. According to posix, <(foo) should direct input from the file named (foo). (Well, that is, according to my reading of the standard. The grammar is ambiguous in many places.)
EDIT: From the bash manual:
The following list is what’s changed when ‘POSIX mode’ is in effect:
...
Process substitution is not available.

Using sed within "while read" expression

I am pretty stuck with that script.
#!/bin/bash
STARTDIR=$1
MNTDIR=/tmp/test/mnt
find $STARTDIR -type l |
while read file;
do
echo Found symlink file: $file
DIR=`sed 's|/\w*$||'`
MKDIR=${MNTDIR}${DIR}
mkdir -p $MKDIR
cp -L $file $MKDIR
done
I passing some directory to $1 parameter, this directory have three symbolic links. In while statement echoed only first match, after using sed I lost all other matches.
Look for output below:
[artyom#LBOX tmp]$ ls -lh /tmp/imp/
total 16K
lrwxrwxrwx 1 artyom adm 19 Aug 8 10:33 ok1 -> /tmp/imp/sym3/file1
lrwxrwxrwx 1 artyom adm 19 Aug 8 09:19 ok2 -> /tmp/imp/sym2/file2
lrwxrwxrwx 1 artyom adm 19 Aug 8 10:32 ok3 -> /tmp/imp/sym3/file3
[artyom#LBOX tmp]$ ./copy.sh /tmp/imp/
Found symlink file: /tmp/imp/ok1
[artyom#LBOX tmp]$
Can somebody help with that issue?
Thanks
You forgot to feed something to sed. Without explicit input, it reads nothing in this construction. I wouldn't use this approach anyway, but just use something like:
DIR=`dirname "$file"`

Resources