字符串测试中的子字符串在unix shell中为测试生成空变量

时间:2017-08-26 13:05:39

标签: string unix substring freebsd

我已经很好地阅读了How do you tell if a string contains another string in Unix shell scripting?,但我很难将我的代码作为一个例子。

我在默认的FreeBSD shell / bin / sh中这样做。请不要bash回答。

这是我的代码

while
        : ${start=$i}
        var1="$(command | awk -v awk_i=$i  'NR==awk_i { print $1 }')" 
                if test ${var1#*$var2} = $var2
                then
                        row=$i
                        break
                fi
        i="$(( $i+1 ))"
        [ "$i" -lt $iterate ]
do :;
done

我知道var1工作正常,因为测试失败并继续迭代整个系列直到结束。问题是当测试通过时,var1的变量为空。

这是一些调试输出,我们发生了迭代,找到了var2的正确值,理论上传递了测试,然后因为变量没有正确地表示为测试的一部分,所以它继续进行。

+ awk -v 'awk_i=27' 'NR==awk_i { print $1 }'
+ var1=file/path/variable
+ test file/path/variable '=' var2
+ i=28
+ [ 28 -lt 52 ]
+ :
+ : 2
+ command
+ awk -v 'awk_i=28' 'NR==awk_i { print $1 }'
+ var1=file/path/variable
+ test '=' var2
test: =: unexpected operator
+ i=29
+ [ 29 -lt 52 ]
+ :
+ : 2
+ command
+ awk -v 'awk_i=29' 'NR==awk_i { print $1 }'
+ var1=file/path/variable
+ test file/path/variable '=' var2
+ i=30
+ [ 30 -lt 52 ]

我甚至尝试过这种替代方法: ##*/ use in UNIX Shell Scripting

if ${var1##*/$var2} = $var2

任何人都可以提出任何建议,为什么变量结尾为空,因此测试无法正确输入?是/那可能造成破坏? (虽然其他输出似乎很好)

由于

1 个答案:

答案 0 :(得分:0)

这样的事情可能会有所帮助:

public class VideoCapture extends AppCompatActivity {
    static final int REQUEST_CODE_CAMERA = 0;
    static final int REQUEST_CODE_EXTERNAL_WRITE = 1;
    static final int REQUEST_CODE_MICROPHONE = 2;

    static SparseIntArray ORIENTATIONS = new SparseIntArray();

    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 0);
        ORIENTATIONS.append(Surface.ROTATION_90, 90);
        ORIENTATIONS.append(Surface.ROTATION_180, 180);
        ORIENTATIONS.append(Surface.ROTATION_270, 270);
    }

    static class CompareSizeByArea implements Comparator<Size> {
        @Override
        public int compare(Size lhs, Size rhs) {
            return Long.signum((long) (lhs.getWidth() * lhs.getHeight()) - (long) (rhs.getWidth() * rhs.getHeight()));
        }
    }

    File videoFolder;
    File videoFile;

    ImageButton recordButton;
    Chronometer chronometer;

    String cameraID;
    MediaRecorder mediaRecorder;

    Size previewSize;
    Size videoSize;
    int totalRotation;

    boolean isRecording;

    HandlerThread backgroundHandlerThread;
    Handler backgroundHandler;

    CaptureRequest.Builder captureRequestBuilder;
    CameraCaptureSession previewCaptureSession;
    CameraCaptureSession recordCaptureSession;

    TextureView textureView;
    TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            setupCamera(width, height);
            startCamera();
            Log.e("onSurfaceTextureAvail", "startCamera width:"+String.valueOf(width)+" height" +String.valueOf(height));
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            Log.e("onSurfaceTextureDestroy","Surface destroyed" + String.valueOf(surface));
            return false;
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            Log.e("onSurfaceTextureSizeCha","Surface changed" + String.valueOf(surface) +"width" +String.valueOf(width)+" height" +String.valueOf(height));
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {

        }
    };

    CameraDevice cameraDevice;
    CameraDevice.StateCallback cameraDeviceStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice camera) {
            cameraDevice = camera;
            mediaRecorder = new MediaRecorder();
            Log.e("cameraDeviceStateCalbac","onOpened mediaRecorder = new MediaRecorder(); camera:"+String.valueOf(camera));

            /**
             * Application will "Reset" when granting write storage permission and call onPause and onResume.
             * The check is to ensure that the camera will correctly follow up with start record.
             **/

            Log.e("cameraDeviceStateCalbac", "onOpened calling startPreview");
            startPreview();
        }

        @Override
        public void onDisconnected(CameraDevice camera) {
            Log.e("cameraDeviceStateCalbac", "onDisconnected closing camera" + String.valueOf(camera));
            camera.close();
            cameraDevice = null;
            Log.e("cameraDeviceStateCalbac", "onDisconnected nulling camera to value:" + String.valueOf(cameraDevice));
        }

        @Override
        public void onError(CameraDevice camera, int error) {
            Log.e("cameraDeviceStateCalbac", "onError closing camera" + String.valueOf(camera)+"Error value: "+String.valueOf(error));
            camera.close();
            cameraDevice = null;
            Log.e("cameraDeviceStateCalbac", "onError nulling camera to value:" + String.valueOf(cameraDevice));
        }
    };

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            finish();
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_videocapture);

        Log.e("onCreate", "Running");
        if (checkCameraPermission() != PackageManager.PERMISSION_GRANTED) requestCameraPermission();
        if (checkWriteExternalStoragePermission() != PackageManager.PERMISSION_GRANTED)
            requestWriteExternalStoragePermission();
        if (checkMicrophonePermission() != PackageManager.PERMISSION_GRANTED)
            requestMicrophonePermission();

        Log.e("onCreate", "Calling createVideoFolder");
        createVideoFolder();
        isRecording = false;
        Log.e("onCreate", "setting isRecording Value" + String.valueOf(isRecording));

        // Chronometer is the timer during a video recording
        chronometer = (Chronometer) findViewById(R.id.chronometer);
        // TextureView is the container that displays the preview
        textureView = (TextureView) findViewById(R.id.textureView);

        // Set up video capture click handler
        recordButton = (ImageButton) findViewById(R.id.recordButton);
        Log.e("onCreate", "recordButton setOnClickListener");
        recordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) // Record/Stop button click
            {
                Log.e("recordOnClick","RUNNING");
                if (!isRecording) // Start Recording
                {
                    Log.e("recordOnClick","isRecording = false");
                    if (checkCameraPermission() == PackageManager.PERMISSION_GRANTED &&
                            checkWriteExternalStoragePermission() == PackageManager.PERMISSION_GRANTED) {
                        try {


                            isRecording = true;
                            Log.e("recordOnClick"," set isRecording = true. Final value: "+String.valueOf(isRecording));
                            recordButton.setImageResource(R.mipmap.btn_video_busy);

                            Log.e("recordOnClick", "Calling createVideoFile()");
                            createVideoFile();

                            Log.e("recordOnClick", "Calling startRecord()");
                            startRecord();

                            Log.e("recordOnClick", "Calling  mediaRecorder.start()");
                            mediaRecorder.start();
                            Log.e("recordOnClick", "If you see this, mediaRecorder.start() passed.");
                            chronometer.setBase(SystemClock.elapsedRealtime());
                            chronometer.setVisibility(View.VISIBLE);
                            chronometer.start();

                        } catch (IllegalArgumentException iaEx) {
                            Log.e("recordOnClick","click to record failed.");
                            StringWriter writer = new StringWriter();
                            PrintWriter printWriter = new PrintWriter(writer);
                            iaEx.printStackTrace(printWriter);
                            printWriter.flush();
                            String stackTrace = writer.toString();
                            Toast.makeText(getApplicationContext(), stackTrace, Toast.LENGTH_LONG).show();
                        } catch (IOException ex) {
                            Log.e("recordOnClick","click to record failed.");
                        }
                    }
                } else // Stop recording
                {

                    Log.e("recordOnClick","isRecording = true");
                    isRecording = false;
                    Log.e("recordOnClick"," set isRecording = false. Final value: "+String.valueOf(isRecording));
                    chronometer.stop();
                    chronometer.setVisibility(View.INVISIBLE);

                    recordButton.setImageResource(R.mipmap.btn_video_online);

                    Log.e("recordOnClick","Calling mediaRecorder.stop()");
                    mediaRecorder.stop();
                    Log.e("recordOnClick", "If you see this, mediaRecorder.stop() passed.");

                    Log.e("recordOnClick","Calling mediaRecorder.reset()");
                    mediaRecorder.reset();
                    Log.e("recordOnClick", "If you see this, mediaRecorder.reset() passed.");

                    Intent mediaStoreUpdateIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    mediaStoreUpdateIntent.setData(Uri.fromFile(videoFile));
                    sendBroadcast(mediaStoreUpdateIntent);

                    Log.e("recordOnClick","Calling startPreview()");
                    startPreview();
                    Log.e("recordOnClick", "If you see this, startPreview() passed.");

                    Intent intent = new Intent(VideoCapture.this, FrameExtraction.class);
                    intent.putExtra("videoUri", Uri.fromFile(videoFile));
                    Log.e("recordOnClick","Video Uri Saved" + String.valueOf(Uri.fromFile(videoFile)));
                    startActivity(intent);
                    finish();


                }
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_CAMERA) 
        {
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getApplicationContext(), "Application will not be able to capture videos without camera permission.", Toast.LENGTH_SHORT).show();
            }
        } else if (requestCode == REQUEST_CODE_EXTERNAL_WRITE) 
        {
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getApplicationContext(), "Application doesn't have write permission. Videos cannot be saved.", Toast.LENGTH_SHORT).show();
            }
        } else if (requestCode == REQUEST_CODE_MICROPHONE) {
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getApplicationContext(), "Application doesn't have microphone permission. Videos will have no audio.", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        startBackgroundThread();

        if (textureView.isAvailable()) {
            setupCamera(textureView.getWidth(), textureView.getHeight());
            startCamera();
            Log.e("RESUME", "RESUME STARTCAMERA");
        } else {
            textureView.setSurfaceTextureListener(surfaceTextureListener);
            Log.e("RESUME", "ELSE, SET TEXTURE LISTENER");
        }
    }

    @Override
    protected void onPause() {

        Log.e("PAUSE", "PAUSE CloseCAMERA");
        cameraDevice.close();
        cameraDevice = null;
        stopBackgroundThread();
        super.onPause();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocas) {
        super.onWindowFocusChanged(hasFocas);
        View decorView = getWindow().getDecorView();
        if (hasFocas) {
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
        }
    }

    private void setupCamera(int width, int height) {
        Log.e("setupCamera","RUNNING");

        CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            identification number
            for (String currentCameraId : cameraManager.getCameraIdList()) {

                CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(currentCameraId);
                if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT)
                    continue;


                int deviceOrientation = getWindowManager().getDefaultDisplay().getRotation();
                totalRotation = sensorToDeviceRotation(cameraCharacteristics, deviceOrientation);
                boolean swapRotation = totalRotation == 90 || totalRotation == 270;
                int rotatedWidth = width;
                int rotatedHeight = height;
                if (swapRotation) {
                    rotatedWidth = height;
                    rotatedHeight = width;
                }


                StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

                previewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight);
                videoSize = chooseOptimalSize(map.getOutputSizes(MediaRecorder.class), rotatedWidth, rotatedHeight);
                cameraID = currentCameraId;
                return;
            }
        } catch (CameraAccessException e) {
        }
    }

    private int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics, int deviceOrientation) {
        int sensorOrienatation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
        deviceOrientation = ORIENTATIONS.get(deviceOrientation);
        return (sensorOrienatation + deviceOrientation + 360) % 360;
    }

    private Size chooseOptimalSize(Size[] choices, int width, int height) {
        List<Size> bigEnough = new ArrayList<>();
        for (Size option : choices) {

            if (option.getHeight() == option.getWidth() * height / width && option.getWidth() >= width && option.getHeight() >= height) {
                bigEnough.add(option);
            }
        }
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new CompareSizeByArea());
        } else {
            return choices[0];
        }
    }


    private void startCamera() {
        Log.e("startCamera()","RUNNING");
        CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkCameraPermission() == PackageManager.PERMISSION_GRANTED)
                    cameraManager.openCamera(cameraID, cameraDeviceStateCallback, backgroundHandler);
                else {
                    requestCameraPermission();
                }
            } else
                cameraManager.openCamera(cameraID, cameraDeviceStateCallback, backgroundHandler);
        } catch (CameraAccessException e) {
            Log.e("startCamera()", "Failed to cameraManager.openCamera" + String.valueOf(e));
        }
    }


    private void startPreview() {
        Log.e("startPreview","RUNNING");
        SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
        surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
        Surface previewSurface = new Surface(surfaceTexture);

        try {
            captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            captureRequestBuilder.addTarget(previewSurface);

            cameraDevice.createCaptureSession(Arrays.asList(previewSurface),
                    new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(CameraCaptureSession session) {
                            previewCaptureSession = session;
                            try {
                                previewCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler);
                            } catch (CameraAccessException e) {
                            }
                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession session) {
                            Log.e("startPreview", "onConfigureFailed");
                        }
                    }, null);
        } catch (CameraAccessException e) {
            Log.e("startPreviewCATCH", "StartPreview FAILED CATCH: " + String.valueOf(e));
        }
    }


    private void startRecord() {

        try {
            Log.e("startRecord", "RUNNING");

            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
            mediaRecorder.setVideoEncodingBitRate(1000000);
            mediaRecorder.setVideoFrameRate(60);
            mediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight());
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mediaRecorder.setOrientationHint(totalRotation);
        }catch(Exception e){

        }
        try {

            mediaRecorder.prepare();
            Log.e("startRecord","mediaRecorder.prepare()");

            SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
            surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
            Surface previewSurface = new Surface(surfaceTexture);
            Surface recordSurface = mediaRecorder.getSurface();
            captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            captureRequestBuilder.addTarget(previewSurface);
            captureRequestBuilder.addTarget(recordSurface);

            cameraDevice.createCaptureSession(Arrays.asList(previewSurface, recordSurface),
                    new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(CameraCaptureSession session) {
                            recordCaptureSession = session;
                            try {
                                recordCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);
                            } catch (CameraAccessException e) {
                            }
                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession session) {
                        }
                    }, null);
        } catch (IOException ioEx) {
            Log.e("prepare Failed", String.valueOf(ioEx));
        } // mediaRecorder.prepare()
        catch (CameraAccessException caEx) {
        } // cameraDevice.createCaptureSession()
    }


    private void closeCamera() {
        if (cameraDevice != null) {
            cameraDevice.close();
            cameraDevice = null;
        }
        if (mediaRecorder != null) {
            mediaRecorder.reset();

            Log.e("closeCamera()","mediaRecorder.reset()");
            mediaRecorder = null;

            Log.e("closeCamera()","mediaRecorder = null");
        }
    }


    private int checkCameraPermission() {
        return ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA);
    }


    private int checkWriteExternalStoragePermission() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }


    private int checkMicrophonePermission() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
    }


    private void requestCameraPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_CAMERA);
    }


    private void requestWriteExternalStoragePermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_EXTERNAL_WRITE);
    }


    private void requestMicrophonePermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_CODE_MICROPHONE);
    }


    private void createVideoFolder() {
        // Create the folder for video files to be written to if it doesn't exist.
        // Battery Videos is the folder name created under the movies public directory.
        Log.e("createVideoFolder", "RUNNING");
        videoFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "Battery Videos");
        if (!videoFolder.exists()) videoFolder.mkdirs();
    }


    private File createVideoFile() throws IOException {
        String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String fileName = "Video_" + timestamp + ".mp4";
        videoFile = new File(videoFolder, fileName);
        return videoFile;
    }


    private void startBackgroundThread() {
        backgroundHandlerThread = new HandlerThread("Camera2VideoImage");
        backgroundHandlerThread.start();
        backgroundHandler = new Handler(backgroundHandlerThread.getLooper());
    }


    private void stopBackgroundThread() {
        backgroundHandlerThread.quitSafely();
        try {
            backgroundHandlerThread.join();
            backgroundHandlerThread = null;
            backgroundHandler = null;
        } catch (InterruptedException e) {
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
Log.e("onDestroy", "It Happened");
        mediaRecorder.release();
    }
}

在这个基本脚本中,不是多次调用命令 W/System.err: java.io.IOException: prepare failed. W/System.err: at android.media.MediaRecorder._prepare(Native Method) W/System.err: at android.media.MediaRecorder.prepare(MediaRecorder.java:782) W/System.err: at com.application.batterysoc.activity.VideoCapture.startRecord(VideoCapture.java:490) W/System.err: at com.application.batterysoc.activity.VideoCapture.access$600(VideoCapture.java:55) W/System.err: at com.application.batterysoc.activity.VideoCapture$3.onClick(VideoCapture.java:214) W/System.err: at android.view.View.performClick(View.java:4861) W/System.err: at android.view.View$PerformClick.run(View.java:19980) W/System.err: at android.os.Handler.handleCallback(Handler.java:739) W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95) W/System.err: at android.os.Looper.loop(Looper.java:211) W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5373) W/System.err: at java.lang.reflect.Method.invoke(Native Method) W/System.err: at java.lang.reflect.Method.invoke(Method.java:372) W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815) E/recordOnClick: Calling mediaRecorder.start() (在每次交互上)只使用一次,输出后者用于形成/创建变量和自定义条件。