How can I execute a shell script in Swift? - swift

I am creating a macOS app with Swift that needs to download and run a shell script. I have been able to download the script with curl, but I can't run it. I am using a function from this answer to run other commands. When I use the App Sandbox in Xcode, I get the error /bin/bash: ./file.sh: Permission denied. When I try changing file permissions, I get the error chmod: Unable to change file mode on file.sh: Operation not permitted.
Here is my code:
func shell(_ command: String) -> String {
let task = Process()
task.launchPath = "/bin/bash"
task.arguments = ["-c", command]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
return output
}
shell("curl https://www.example.com/file.sh -o file.sh")
shell("./file.sh")
Output:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
1 16.0M 1 224k 0 0 231k 0 0:01:11 --:--:-- 0:01:11 231k
47 16.0M 47 7808k 0 0 4064k 0 0:00:04 0:00:01 0:00:03 4062k
100 16.0M 100 16.0M 0 0 6037k 0 0:00:02 0:00:02 --:--:-- 6037k
/bin/bash: ./file.sh: Permission denied

Related

Running curl.exe in PowerShell

I am trying to recreate a working curl command in PowerShell 5.1, but when I run it from the script, it errors out. If I pipe out the constructed command to a text file and run it as-is in a command shell it works. I resorted to attempting curl in PowerShell because I have been unable to get the multipart/form-data to work with the Invoke-RestMethod function. Here is the code I'm using, and the error message is shown below. This is on Windows 10 machine. In a nutshell, this is to upload a zip file to a remote server.
$accessToken = '<Bearer token value from prior API call>'
$inputFile = 'C:\MyFolder1\MyFolder2\MyFile.zip'
$curlCmd = 'C:\Curl\bin\curl.exe'
$uriImport = 'https://api.somecompany.com/import'
$curlArgs = '-X', 'POST',
'--header', '"Content-Type: multipart/form-data"',
'--header', '"Accept: application/json"',
'--header', -join('"Authorization: Bearer ', $accessToken, '"'),
'--form', -join('"files=#', $inputFile, ';type=application/zip"'),
-join('"', $uriImport, '"'), '-s'
Write-Host "$curlCmd $cURLargs"
"$curlCmd $curlArgs" | Out-File 'C:\MyFolder\MyFolder2\Curl_Output.txt'
& $curlCmd $curlArgs
The error PoSH returns:
curl.exe : % Total % Received % Xferd Average Speed Time Time Time Current
At C:\CurlTesting.ps1:65 char:9
+ & $curCmd $cURLargs
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ( % Total % ... Time Current:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:03 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:04 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:05 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:06 --:--:-- 0
curl: (6) Could not resolve host: multipart
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (6) Could not resolve host: application
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (6) Could not resolve host: Bearer
curl: (3) URL using bad/illegal format or missing URL
I have tried constructing the quotes with both single and double, but it still errors out; the Windows command prompt does require double-quotes. When I run this same constructed script from a command window (cmd.exe), it runs and I don't get all of that output nor the error - just the expected value from the API.
What am I doing wrong?
Here is the modified, slimmed-down version of the code I got working:
$accessToken = '<Bearer token value from prior API call>'
$inputFile = 'C:\MyFolder1\MyFolder2\MyFile.zip'
$uriImport = 'https://api.somecompany.com/import'
curl.exe -X POST `
--header "Content-Type: multipart/form-data" `
--header "Accept: application/json" `
--header "Authorization: Bearer $accessToken" `
--form "filename=#$inputFile;type=application/zip" `
-s
This is what process monitor says is running. It seems ok to me. I don't have that curl but windows 10 (since 1803) comes with curl.exe now. Beware the curl alias in ps 5.
"C:\windows\system32\curl.exe" -X POST --header "Content-Type: multipart/form-data" --header "Accept: application/json" --header "Authorization: Bearer <Bearer token value from prior API call>" --form "files=#C:\MyFolder1\MyFolder2\MyFile.zip;type=application/zip" "https://api.somecompany.com/import" -s
I would run it this way. It's possible that powershell could lose doublequotes to an external command, that you would need to backslash, but this is as much as I can reproduce. It doesn't look like you're running it in silent mode, "-s".
C:\Curl\bin\curl.exe -X POST --header "Content-Type: multipart/form-data" --header "Accept: application/json" --header "Authorization: Bearer $accessToken" --form "files=#$inputFile;type=application/zip" $uriImport -s

Check value of PF_NO_SETAFFINITY

Is it possible to tell whether a process/thread has the PF_NO_SETAFFINITY flag set? I'm running taskset on a series of process ids and some are throwing errors of the following form:
taskset: failed to set pid 30's affinity: Invalid argument
I believe this is because some processes have PF_NO_SETAFFINITY set (see Answer).
Thank you!
Yes - look at /proc/PID/stat's 'flag' field
<linux/sched.h
#define PF_NO_SETAFFINITY 0x04000000 /* Userland is not allowed to meddle with cpus_allowed */
Look here for details on using /proc:
http://man7.org/linux/man-pages/man5/proc.5.html
https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk65143
Example:
ps -eaf
www-data 30084 19962 0 07:09 ? 00:00:00 /usr/sbin/apache2 -k start
...
cat /proc/30084/stat
30084 (apache2) S 19962 19962 19962 0 -1 4194624 554 0 3 0 0 0 0 0 20 0 1 0 298837672 509616128 5510 18446744073709551615 1 1 0 0 0 0 0 16781312 201346799 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0
The flags are 4194624
Q: Do you mind specifying how you'd write a simple script that outputs
true/false based on whether you're allowed to set affinity?
A: I don't feel comfortable providing this without the opportunity to test, but you can try something like this...
flags=$(cut -f 9 -d ' ' /proc/30084/stat)
echo $(($flags & 0x40000000))

Error for REST API in nifi

when i start Executestream prosessor with src.bat file it shows me execution code 0 but it doesn't stop processor and insede outputstream flowfile it shows errors like this:
execution.error
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 299 0 0 100 299 0 1472 --:--:-- --:--:-- --:--:-- 1472
I use commands like this:
curl -X PUT --data-binary "#C:\Users\user\Desktop\nifi-1.3.0\conf\stop.json" "http://localhost:8080/nifi-api/processors/ea5db028-015d-1000-5ad5-80fd006dda92"
and json file like this, what should i do?:
{
"status": {
"runStatus": "STOPPED"
},
"component": {
"state": "STOPPED",
"id": "f511a6a1-015d-1000-970e-969eac1e6fc5"
},
"id": "f511a6a1-015d-1000-970e-969eac1e6fc5",
"revision": {
"version": 30,
"clientId": "0343f0b9-015e-1000-7cd8-570f8953ec11"
}
}
I suspect that if curl is reporting progress then somehow the output/process is reporting strangely to NiFi. Perhaps try the "silent" option for your curl command (see the documentation for how to enable that, often it's the -s flag)

Hung processes resume if attached to strace

I have a network program written in C using TCP sockets. Sometimes the client program hangs forever expecting input from server. Specifically, the client hangs on select() call set on an fd intended to read characters sent by server.
I am using strace to know where the process got stuck. However, sometimes when I attach the hung client process to strace, it immediately resumes it's execution and properly exits. Not all hung processes exhibit this behavior, some processes stuck in the select() even if I attach them to strace. But most of the processes resume their execution when attached to strace.
I am curious what causing the processes resume when attached to strace. It might give me clues to know why client processes are getting hung.
Any ideas? what causes a hung process to resume it's execution when attached to strace?
Update:
Here's the output of strace on hung processes.
> sudo strace -p 25645
Process 25645 attached - interrupt to quit
--- SIGSTOP (Stopped (signal)) # 0 (0) ---
--- SIGSTOP (Stopped (signal)) # 0 (0) ---
[ Process PID=25645 runs in 32 bit mode. ]
select(6, [3 5], NULL, NULL, NULL) = 2 (in [3 5])
read(5, "\0", 8192) = 1
write(2, "", 0) = 0
read(3, "====Setup set_oldtempbehaio"..., 8192) = 555
write(1, "====Setup set_oldtempbehaio"..., 555) = 555
select(6, [3 5], NULL, NULL, NULL) = 2 (in [3 5])
read(5, "", 8192) = 0
read(3, "", 8192) = 0
close(5) = 0
kill(25652, SIGKILL) = 0
exit_group(0) = ?
Process 25645 detached
_
> sudo strace -p 14462
Process 14462 attached - interrupt to quit
[ Process PID=14462 runs in 32 bit mode. ]
read(0, 0xff85fdbc, 8192) = -1 EIO (Input/output error)
shutdown(3, 1 /* send */) = 0
exit_group(0) = ?
_
> sudo strace -p 7517
Process 7517 attached - interrupt to quit
--- SIGSTOP (Stopped (signal)) # 0 (0) ---
--- SIGSTOP (Stopped (signal)) # 0 (0) ---
[ Process PID=7517 runs in 32 bit mode. ]
connect(3, {sa_family=AF_INET, sin_port=htons(300), sin_addr=inet_addr("100.64.220.98")}, 16) = -1 ETIMEDOUT (Connection timed out)
close(3) = 0
dup(2) = 3
fcntl64(3, F_GETFL) = 0x1 (flags O_WRONLY)
close(3) = 0
write(2, "dsd13: Connection timed out\n", 30) = 30
write(2, "Error code : 110\n", 17) = 17
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
exit_group(1) = ?
Process 7517 detached
Not just select(), but the processes(of same program) are stuck in various system calls before I attach them to strace. They suddenly resume after attaching to strace. If I don't attach them to strace, they just hang there forever.
Update 2:
I learned that strace could start a process which was previously stopped (process in T sate). Now I am trying to understand why did these processes go to 'T' state, what's the cause. Here's the /proc//status information:
> cat /proc/12554/status
Name: someone
State: T (stopped)
SleepAVG: 88%
Tgid: 12554
Pid: 12554
PPid: 9754
TracerPid: 0
Uid: 5000 5000 5000 5000
Gid: 48986 48986 48986 48986
FDSize: 256
Groups: 9149 48986
VmPeak: 1992 kB
VmSize: 1964 kB
VmLck: 0 kB
VmHWM: 608 kB
VmRSS: 608 kB
VmData: 156 kB
VmStk: 20 kB
VmExe: 16 kB
VmLib: 1744 kB
VmPTE: 20 kB
Threads: 1
SigQ: 54/73728
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000006
SigCgt: 0000000000004000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Cpus_allowed: 00000000,00000000,00000000,0000000f
Mems_allowed: 00000000,00000001
strace uses ptrace. The ptrace man page has this:
Since attaching sends SIGSTOP and the tracer usually suppresses it,
this may cause a stray EINTR return from the currently executing system
call in the tracee, as described in the "Signal injection and
suppression" section.
Are you seeing select return EINTR?

prstat on solaris - can you make it flash when size exceeds a limit?

I have been told to make prstat flash the background from white to black a few times when any value in the size category passes a threshold. Is there a way to edit the command and put this in here or will this never happen?
I'm not trying to be mean, but somebody who asked for this is not being reasonable or does not understand. I would guess the "asker" has no clue about prstat. Look at these two examples:
example% prstat -u root -n 5 -P 1,2 1 1
PID USERNAME SWAP RSS STATE PRI NICE TIME CPU PROCESS/LWP
306 root 3024K 1448K sleep 58 0 0:00.00 0.3% sendmail/1
102 root 1600K 592K sleep 59 0 0:00.00 0.1% in.rdisc/1
250 root 1000K 552K sleep 58 0 0:00.00 0.0% utmpd/1
288 root 1720K 1032K sleep 58 0 0:00.00 0.0% sac/1
1 root 744K 168K sleep 58 0 0:00.00 0.0% init/1
TOTAL: 25, load averages: 0.05, 0.08, 0.12
example% prstat -S rss -n 5 -vc -u root,john
PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWP
1 root 0.0 0.0 - - - - 100 - 0 0 0 0 init/1
102 root 0.0 0.0 - - - - 100 - 0 0 3 0 in.rdisc/1
250 root 0.0 0.0 - - - - 100 - 0 0 0 0 utmpd/1
1185 john 0.0 0.0 - - - - 100 - 0 0 0 0 csh/1
240 root 0.0 0.0 - - - - 100 - 0 0 0 0 powerd/4
TOTAL: 71, load averages: 0.02, 0.04, 0.08
So, what value do you look for? There are lots of things prstat displays, so you have to learn all of them then code for whatever each of the many possible outputs means.
To do this:
What you will have to do is to run prstat with arguments entered on the command line, in a child process, read and interpret everything it produces, then map it to output and flash the screen as appropriate. You can do this with coprocesses in ksh or zsh or by using fifos in bash. Consider running prtstat in -e mode regardless of the what the user enters so you have full screens to read and manipulate.
Flashing the screen can be done with escape sequences, like changing background color or whatever you want. Here is a starting point for Windows based terminals:
ANSI escape sequences
And for Vt100 (UNIX)
terminal escape codes