Can not figure out how to run a file stored in a variable found with 'find' in shell script in Terminal on OSX - bash

The code I have at the moment is:
#!/bin/bash
cd "/Users/{User}/Documents/jarfiles/"
runnable_game=$(find . -type f -name 'game\..*\.jar')
echo $runnable_game
eval $runnable_game
in my Documents folder I have a folder jarfiles and within that folder there is only 1 jar file, although if possible only make it select the first file found.
The goal is to execute this file. for example: /Documents/jarfiles/game.1234.jar should be run.
for debug I put an echo in there, but the echo returned nothing, a blank line.
I have some programming skill, but I am not professional and in no way used to shell scripts or terminal command line magic. (I program in Java, C and such...)
Any idea to make a script that finds a file and runs it?
to clarify:
I don't know the filename in advance any .jar file to that format should be run, basically I download a file to that directory which is in that format

To execute a jar file you know is there but you don't know the exact name,
you can use a simple shell wildcard,
you don't need the find command:
java -jar game*.jar
If you want to execute only the first file found, then find can be indeed useful:
find . -name 'game*.jar' -exec java -jar {} \; -quit

Correct shell code to run 'game' + any string + 'jar'
#!/bin/bash
cd "/Users/{User}/Documents/jarfiles"
java -jar $(find . -name 'game.*jar')
game\..*\.jar escaping using \ seemed to not work
this will find files starting with game and ending with jar, not game. and .jar, which is not a problem (at the moment).

Related

Ansible shell calling find to exclude file with today date

My team is facing issues with Ansible shell command.
I've a directory with log files to zip and the previous processed files (which are zipped), all files are timestamped as YYYY.mm.dd like :
somefile.2021.05.19.log
somefile.2021.05.20.log
somefile.2021.06.18.log.gz
I need to zip the ones which does not contain the current date (if today is 2021.05.20, I won't zip this file). It means in the exemple above, only the somefile.2021.05.19.log must be zipped.
I'm using the shell command :
find /var/log/somedirectory -type f ! -name "*.gz" ! -path "*`date +%Y.%m.%d`*" -exec gzip -9 {} \;
which is working fine in Linux shell and doing what I need to do : does not take *.gz files, and not the one with current date.
We're migrating from a previous orchestrator to Ansible.
When using Ansible shell with this command, it doesn't filter on the date like if the -path was not well translated from Ansible to the shell.
We tried to espace " or backtick or * but nothing seems to work. It always take the 2021.05.19 file AND unfortunately the 2021.05.20 file.
Is there some way to use this command (or a better one) in Ansible ?
Thanks.

Is it possible to run a command from /bin directory of a project from a sub directory?

I have a c5 project with a directory C5PROJECTDIR it has a bin directory. Is there a way (without adding C5PROJECTDIR/bin to $PATH) to access commands from any other subdirectory of C5PROJECTDIR?
For example:
There is an x command located here: C5PROJECTDIR/bin/x.
I want to run this command from a bash script from C5PROJECTDIR/packages/some-other-dir.
UPDATE: The sub directory can be more or less deeper in the tree...
How can it be possible?
There are a few ways:
Use relative paths:
Essentially call the binary directly with its path, but relative to the current script. If your script is located in /home/user/foo/C5PROJECTDIR/packages/somedir/script, then you call the script relatively:
#!/usr/bin/env bash
../../bin/x
The problem with this method is maintainability. Imagine you want to move your script to /home/user/foo/C5PROJECTDIR/packages/scripts, then you would have to update all your scripts.
Use a shell variable:
Instead of relative paths, you can define a variable PROJECTHOME which contains the base value.
#!/usr/bin/env bash
PROJECTHOME=/home/user/foo/C5PROJECTDIR
$PROJECTHOME/bin/x
This generally solves most problems unless you move project location from /home/user/foo/C5PROJECTDIR to /home/user/random-dir. But this can be solved with a simple sed command that searches for the line /home/user/foo/C5PROJECTDIR and replaces it.
PATH variable only make things easier.
You able to run any commands with absolute path like /bin/echo or /home/jon/myscript. Relative path works as well ~/../../bin/ls.
Script have its own PATH variable, so you can add the desired location to PATH in your script if you like.
Apart from this you have to deal with permissions.
The user that have script executed by, must have execute permission on the x script.
To find and execute command:
find C5PROJECTDIR -type f -executable -name "x" -exec {} \;
Find's must be strict to match only one command else it will execute all that it fund. You cannot have script with the same name under C5PROJECTDIR in this case.
From security point of view. I do not recommend this, as anyone can put an executable file under C5PROJECTDIR with a name used in the script. things can go nasty.

Find and execute command on all files in directory that have a specific folder name

I want to use the find command to execute a special command on all of the files inside the directory that are contained inside multiple different directories with a specific keyword in it (the keyword is "Alpha") and keep the output inside the working directory of the initial file I ran the command on.
The command works such that it requires to you to provide the initial file to perform the command on and then the name of the newly converted file. So like this
command file_to_run_command_on.txt new_file.txt
This is my code
find $PWD -name *.txt* -exec command {} new_file. \;
Right now, it finds all the text files in this directory even in the sub directories and outputs just one file in the directory I run the initial find command from. I'm also unsure how to add the additional search for the keyword in the directory. All advice appreciated!
-exec runs the command in the directory from which you start find.
-execdir runs the command in the matching file's directory.
To only find *.txt* files whose parents contain a specific file, you could use:
find "$PWD" -path "*keyword*/*.txt*" -execdir command {} new_file \;
This will run the command for foo/bar/some-keyword-dir/baz/etc/file.txts but not for foo/bar/baz/file.txts (no keyword in parent directory names) or foo/bar/some-keyword-dir/baz/file.tar (not *.txt*)

How to copy files and add prefix at the same time?

I am not familiar with osx terminal command.
I have a java project containing many package.
Some classes have same name in different package.
I need to copy all of the class files into a directory, so I need to add
corresponding package prefix on each files.
For example, I have root/com/example1/test.java and root/com/example2/test.java two classes having the same name in different packages. I need to copy them into root directory and add prefix, making them become example1.test.java and example2.test.java in root directory.
How to do this using terminal command?
This solution is not perfect but it should do what you want (assuming I understood your question correctly):
Create a file doCopy.sh with the following content:
#!/bin/bash
origName=$1
newName=$(echo $origName | sed -e 's|/|.|g')
echo cp $origName $newName
Then make it executable and call it for each of your files:
chmod +x doCopy.sh
find root -type f -exec ./doCopy.sh {} \;
Please verify the commands that will be printed. If you are satisfied you can remove the echo from doCopy.sh and rerun the find to actually copy the files.

Execute command from another directory without really moving

Consider this directory structure
/dir1/Quack.sh
/dir2/ <- We are here
Is it possible to execute Quack.sh as if I were currently in /dir1/ without actually cd'ing there?
The main reason I'm asking is because Bundle is complaining when running executables who depends on it when the executable is ran from outside the folder. The executable runs fine if executed from the directory it is contained in.
You can create sub-shell and do cd, script execution:
(cd ../dir1/; ./Quack.sh)
OR else use find -execdir
find ../dir2/ -maxdepth1 -name "Quack.sh" -execdir '{}' \;

Resources